[PATCH] D23981: Add StringRef::scan_between

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 28 21:31:37 PDT 2016


zturner created this revision.
zturner added a subscriber: llvm-commits.

A common pattern is something like this:

```
// S is of the form "foo[bar]baz", get bar out.
size_t open = S.find("[");
if (open != npos) {
  size_t close = S.find("]", open);
  if (close != npos) {
    StringRef middle = S.slice(open, close);
    // Do something
  }
}
```

I want to simplify the above by turning it into one line:

```
StringRef middle = S.scan_between("[", "]");
```

This patch addresses this.

https://reviews.llvm.org/D23981

Files:
  include/llvm/ADT/StringRef.h
  unittests/ADT/StringRefTest.cpp

Index: unittests/ADT/StringRefTest.cpp
===================================================================
--- unittests/ADT/StringRefTest.cpp
+++ unittests/ADT/StringRefTest.cpp
@@ -373,6 +373,16 @@
   EXPECT_TRUE(Str.consume_back(""));
 }
 
+TEST(StringRefTest, ScanBetween) {
+  StringRef Str("StringRefTest::ScanBetween()");
+  EXPECT_EQ(Str, Str.scan_between("", ""));
+  EXPECT_EQ("StringRefTest", Str.scan_between("", "::"));
+  EXPECT_EQ("ScanBetween()", Str.scan_between("::", ""));
+  EXPECT_EQ("ScanBetween", Str.scan_between("::", "()"));
+  EXPECT_EQ("::ScanBetween()", Str.scan_between("StringRefTest", "ABCDE"));
+  EXPECT_EQ("", Str.scan_between("ABCDE", "::"));
+}
+
 TEST(StringRefTest, Find) {
   StringRef Str("hello");
   EXPECT_EQ(2U, Str.find('l'));
Index: include/llvm/ADT/StringRef.h
===================================================================
--- include/llvm/ADT/StringRef.h
+++ include/llvm/ADT/StringRef.h
@@ -17,6 +17,7 @@
 #include <cstring>
 #include <limits>
 #include <string>
+#include <tuple>
 #include <utility>
 
 namespace llvm {
@@ -337,6 +338,10 @@
     /// Complexity: O(size() + Chars.size())
     size_t find_last_not_of(StringRef Chars, size_t From = npos) const;
 
+    /// Check if the specified substring is contained in this string, and
+    /// return a boolean indicating success or failure.
+    bool contains(llvm::StringRef Str) const { return find(Str) != npos; }
+
     /// @}
     /// @name Helpful Algorithms
     /// @{
@@ -492,6 +497,22 @@
       return true;
     }
 
+    /// Returns a StringRef representing the first occurrence of a string Result
+    /// such that \p Left + Result + \p Right is a substring of *this.  When
+    /// \p Left is empty, the result is taken from the beginning of the string
+    /// and when \p Right is empty, the result runs up until the end of the
+    /// string.
+    LLVM_ATTRIBUTE_ALWAYS_INLINE
+    LLVM_ATTRIBUTE_UNUSED_RESULT
+    StringRef scan_between(StringRef Left, StringRef Right) const {
+      StringRef A, B;
+      std::tie(A, B) = split(Left);
+      if (Right.empty())
+        return B;
+      std::tie(B, A) = B.split(Right);
+      return B;
+    }
+
     /// Return a reference to the substring from [Start, End).
     ///
     /// \param Start The index of the starting character in the substring; if


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D23981.69529.patch
Type: text/x-patch
Size: 2331 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160829/ea842267/attachment-0001.bin>


More information about the llvm-commits mailing list