diff --git a/llvm/include/llvm/Support/FormatProviders.h b/llvm/include/llvm/Support/FormatProviders.h --- a/llvm/include/llvm/Support/FormatProviders.h +++ b/llvm/include/llvm/Support/FormatProviders.h @@ -355,7 +355,6 @@ 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 @@ 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 --- a/llvm/unittests/Support/FormatVariadicTest.cpp +++ b/llvm/unittests/Support/FormatVariadicTest.cpp @@ -698,3 +698,31 @@ 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