diff --git a/llvm/include/llvm/ADT/StringRef.h b/llvm/include/llvm/ADT/StringRef.h index 049f22b03e46e..952d6485dafc1 100644 --- a/llvm/include/llvm/ADT/StringRef.h +++ b/llvm/include/llvm/ADT/StringRef.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -54,6 +55,9 @@ namespace llvm { using iterator = const char *; using const_iterator = const char *; using size_type = size_t; + using value_type = char; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; private: /// The start of the string, in an external buffer. @@ -112,6 +116,14 @@ namespace llvm { iterator end() const { return Data + Length; } + reverse_iterator rbegin() const { + return std::make_reverse_iterator(end()); + } + + reverse_iterator rend() const { + return std::make_reverse_iterator(begin()); + } + const unsigned char *bytes_begin() const { return reinterpret_cast(begin()); } diff --git a/llvm/unittests/ADT/StringRefTest.cpp b/llvm/unittests/ADT/StringRefTest.cpp index a0529b03ae8c2..ec9cdc197597d 100644 --- a/llvm/unittests/ADT/StringRefTest.cpp +++ b/llvm/unittests/ADT/StringRefTest.cpp @@ -57,9 +57,17 @@ TEST(StringRefTest, EmptyInitializerList) { TEST(StringRefTest, Iteration) { StringRef S("hello"); - const char *p = "hello"; - for (const char *it = S.begin(), *ie = S.end(); it != ie; ++it, ++p) - EXPECT_EQ(*it, *p); + constexpr StringLiteral CS("hello"); + + // Note: Cannot use literal strings in equal() as iteration over a literal + // string includes the null terminator. + const std::string_view RefFwd("hello"); + const std::string_view RefRev("olleh"); + + EXPECT_TRUE(equal(S, RefFwd)); + EXPECT_TRUE(equal(CS, RefFwd)); + EXPECT_TRUE(equal(make_range(S.rbegin(), S.rend()), RefRev)); + EXPECT_TRUE(equal(make_range(CS.rbegin(), CS.rend()), RefRev)); } TEST(StringRefTest, StringOps) {