From 791bdba0b183371ca3e16bb8411a059b4f8636ac Mon Sep 17 00:00:00 2001 From: Vladislav Vinogradov Date: Wed, 2 Nov 2022 14:22:14 +0300 Subject: [PATCH] [Support] Format provider improvements Remove `std::forward` call for `iterator_range` iterator de-reference. It fixes formatting usage for some tricky cases, like special ranges, which de-reference to value type. Reviewed By: sammccall Differential Revision: https://reviews.llvm.org/D94769 --- llvm/include/llvm/Support/FormatProviders.h | 7 ++----- llvm/unittests/Support/FormatVariadicTest.cpp | 28 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/llvm/include/llvm/Support/FormatProviders.h b/llvm/include/llvm/Support/FormatProviders.h index 2bdc316..c25453e 100644 --- a/llvm/include/llvm/Support/FormatProviders.h +++ b/llvm/include/llvm/Support/FormatProviders.h @@ -355,7 +355,6 @@ struct range_item_has_provider template class format_provider> { using value = typename std::iterator_traits::value_type; - using reference = typename std::iterator_traits::reference; static StringRef consumeOneOption(StringRef &Style, char Indicator, StringRef Default) { @@ -403,15 +402,13 @@ public: auto Begin = V.begin(); auto End = V.end(); if (Begin != End) { - auto Adapter = - detail::build_format_adapter(std::forward(*Begin)); + auto Adapter = detail::build_format_adapter(*Begin); Adapter.format(Stream, ArgStyle); ++Begin; } while (Begin != End) { Stream << Sep; - auto Adapter = - detail::build_format_adapter(std::forward(*Begin)); + auto Adapter = detail::build_format_adapter(*Begin); Adapter.format(Stream, ArgStyle); ++Begin; } diff --git a/llvm/unittests/Support/FormatVariadicTest.cpp b/llvm/unittests/Support/FormatVariadicTest.cpp index 40c94b7..44e4477 100644 --- a/llvm/unittests/Support/FormatVariadicTest.cpp +++ b/llvm/unittests/Support/FormatVariadicTest.cpp @@ -697,3 +697,31 @@ TEST(FormatVariadicTest, FormatError) { EXPECT_EQ("X", formatv("{0}", fmt_consume(std::move(E1))).str()); EXPECT_FALSE(E1.isA()); // consumed } + +TEST(FormatVariadicTest, FormatFilterRange) { + std::vector Vec{0, 1, 2}; + auto Range = map_range(Vec, [](int V) { return V + 1; }); + EXPECT_EQ("1, 2, 3", formatv("{0}", Range).str()); +} + +namespace { + +class IntegerValuesRange final + : public indexed_accessor_range { +public: + using indexed_accessor_range::indexed_accessor_range; + + static int dereference(const NoneType &, ptrdiff_t Index) { + return static_cast(Index); + } +}; + +TEST(FormatVariadicTest, FormatRangeNonRef) { + IntegerValuesRange Range(None, 0, 3); + EXPECT_EQ("0, 1, 2", + formatv("{0}", make_range(Range.begin(), Range.end())).str()); +} + +} // namespace -- 2.7.4