mirror of
https://github.com/fmtlib/fmt.git
synced 2025-07-31 19:24:48 +02:00
Fix formatting of ranges with begin()&/end()&
C++20 allows ranges to have lvalue-qualified begin() and end() member functions. fmt correctly handles this if begin() and end() are additionally const-qualifed (i.e. begin() const&), but not in the non-const case. For example: https://godbolt.org/z/YfxaYz5r7 This patch fixes fmt's range detection to handle this case by testing calls to detail::ranges_begin()/end() with an lvalue T&, matching the behaviour in the const case.
This commit is contained in:
committed by
Victor Zverovich
parent
6f5d53ce08
commit
2595bf57b3
@@ -132,8 +132,8 @@ struct has_const_begin_end<
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct has_mutable_begin_end<
|
struct has_mutable_begin_end<
|
||||||
T, void_t<decltype(detail::range_begin(std::declval<T>())),
|
T, void_t<decltype(detail::range_begin(std::declval<T&>())),
|
||||||
decltype(detail::range_end(std::declval<T>())),
|
decltype(detail::range_end(std::declval<T&>())),
|
||||||
// the extra int here is because older versions of MSVC don't
|
// the extra int here is because older versions of MSVC don't
|
||||||
// SFINAE properly unless there are distinct types
|
// SFINAE properly unless there are distinct types
|
||||||
int>> : std::true_type {};
|
int>> : std::true_type {};
|
||||||
|
@@ -592,3 +592,14 @@ auto format_as(const tieable& t) -> std::tuple<int, double> {
|
|||||||
TEST(ranges_test, format_as_tie) {
|
TEST(ranges_test, format_as_tie) {
|
||||||
EXPECT_EQ(fmt::format("{}", tieable()), "(3, 0.42)");
|
EXPECT_EQ(fmt::format("{}", tieable()), "(3, 0.42)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct lvalue_qualified_begin_end {
|
||||||
|
int arr[5] = {1, 2, 3, 4, 5};
|
||||||
|
|
||||||
|
int const* begin() & { return arr; }
|
||||||
|
int const* end() & { return arr + 5; }
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST(ranges_test, lvalue_qualified_begin_end) {
|
||||||
|
EXPECT_EQ(fmt::format("{}", lvalue_qualified_begin_end{}), "[1, 2, 3, 4, 5]");
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user