Permalink
Browse files

Add startsWith, endsWith, removePrefix, removeSuffix to folly::Range

Summary:
Yes, I know about boost::starts_with, but I think the convenience is worth it.
Also, I've written then equivalent of removePrefix / removeSuffix way too
many times.

Test Plan: test added

Reviewed By: andrei.alexandrescu@fb.com

FB internal diff: D1106425
  • Loading branch information...
1 parent 1ceb5ed commit c84a6adfa129a50fc4d16df8a290a613ed548e82 @tudor tudor committed with jdelong Dec 19, 2013
Showing with 163 additions and 0 deletions.
  1. +42 −0 folly/Range.h
  2. +121 −0 folly/test/RangeTest.cpp
View
@@ -455,6 +455,48 @@ class Range : private boost::totally_ordered<Range<Iter> > {
std::swap(e_, rhs.e_);
}
+ /**
+ * Does this Range start with another range?
+ */
+ bool startsWith(const Range& other) const {
+ return size() >= other.size() && subpiece(0, other.size()) == other;
+ }
+ bool startsWith(value_type c) const {
+ return !empty() && front() == c;
+ }
+
+ /**
+ * Does this Range end with another range?
+ */
+ bool endsWith(const Range& other) const {
+ return size() >= other.size() && subpiece(size() - other.size()) == other;
+ }
+ bool endsWith(value_type c) const {
+ return !empty() && back() == c;
+ }
+
+ /**
+ * Remove the given prefix and return true if the range starts with the given
+ * prefix; return false otherwise.
+ */
+ bool removePrefix(const Range& prefix) {
+ return startsWith(prefix) && (b_ += prefix.size(), true);
+ }
+ bool removePrefix(value_type prefix) {
+ return startsWith(prefix) && (++b_, true);
+ }
+
+ /**
+ * Remove the given suffix and return true if the range ends with the given
+ * suffix; return false otherwise.
+ */
+ bool removeSuffix(const Range& suffix) {
+ return endsWith(suffix) && (e_ -= suffix.size(), true);
+ }
+ bool removeSuffix(value_type suffix) {
+ return endsWith(suffix) && (--e_, true);
+ }
+
private:
Iter b_, e_;
};
View
@@ -302,6 +302,126 @@ TEST(StringPiece, Constexpr) {
}
#endif
+TEST(StringPiece, Prefix) {
+ StringPiece a("hello");
+ EXPECT_TRUE(a.startsWith(""));
+ EXPECT_TRUE(a.startsWith("h"));
+ EXPECT_TRUE(a.startsWith('h'));
+ EXPECT_TRUE(a.startsWith("hello"));
+ EXPECT_FALSE(a.startsWith("hellox"));
+ EXPECT_FALSE(a.startsWith('x'));
+ EXPECT_FALSE(a.startsWith("x"));
+
+ {
+ auto b = a;
+ EXPECT_TRUE(b.removePrefix(""));
+ EXPECT_EQ("hello", b);
+ }
+ {
+ auto b = a;
+ EXPECT_TRUE(b.removePrefix("h"));
+ EXPECT_EQ("ello", b);
+ }
+ {
+ auto b = a;
+ EXPECT_TRUE(b.removePrefix('h'));
+ EXPECT_EQ("ello", b);
+ }
+ {
+ auto b = a;
+ EXPECT_TRUE(b.removePrefix("hello"));
+ EXPECT_EQ("", b);
+ }
+ {
+ auto b = a;
+ EXPECT_FALSE(b.removePrefix("hellox"));
+ EXPECT_EQ("hello", b);
+ }
+ {
+ auto b = a;
+ EXPECT_FALSE(b.removePrefix("x"));
+ EXPECT_EQ("hello", b);
+ }
+ {
+ auto b = a;
+ EXPECT_FALSE(b.removePrefix('x'));
+ EXPECT_EQ("hello", b);
+ }
+}
+
+TEST(StringPiece, Suffix) {
+ StringPiece a("hello");
+ EXPECT_TRUE(a.endsWith(""));
+ EXPECT_TRUE(a.endsWith("o"));
+ EXPECT_TRUE(a.endsWith('o'));
+ EXPECT_TRUE(a.endsWith("hello"));
+ EXPECT_FALSE(a.endsWith("xhello"));
+ EXPECT_FALSE(a.endsWith("x"));
+ EXPECT_FALSE(a.endsWith('x'));
+
+ {
+ auto b = a;
+ EXPECT_TRUE(b.removeSuffix(""));
+ EXPECT_EQ("hello", b);
+ }
+ {
+ auto b = a;
+ EXPECT_TRUE(b.removeSuffix("o"));
+ EXPECT_EQ("hell", b);
+ }
+ {
+ auto b = a;
+ EXPECT_TRUE(b.removeSuffix('o'));
+ EXPECT_EQ("hell", b);
+ }
+ {
+ auto b = a;
+ EXPECT_TRUE(b.removeSuffix("hello"));
+ EXPECT_EQ("", b);
+ }
+ {
+ auto b = a;
+ EXPECT_FALSE(b.removeSuffix("xhello"));
+ EXPECT_EQ("hello", b);
+ }
+ {
+ auto b = a;
+ EXPECT_FALSE(b.removeSuffix("x"));
+ EXPECT_EQ("hello", b);
+ }
+ {
+ auto b = a;
+ EXPECT_FALSE(b.removeSuffix('x'));
+ EXPECT_EQ("hello", b);
+ }
+}
+
+TEST(StringPiece, PrefixEmpty) {
+ StringPiece a;
+ EXPECT_TRUE(a.startsWith(""));
+ EXPECT_FALSE(a.startsWith("a"));
+ EXPECT_FALSE(a.startsWith('a'));
+ EXPECT_TRUE(a.removePrefix(""));
+ EXPECT_EQ("", a);
+ EXPECT_FALSE(a.removePrefix("a"));
+ EXPECT_EQ("", a);
+ EXPECT_FALSE(a.removePrefix('a'));
+ EXPECT_EQ("", a);
+}
+
+TEST(StringPiece, SuffixEmpty) {
+ StringPiece a;
+ EXPECT_TRUE(a.endsWith(""));
+ EXPECT_FALSE(a.endsWith("a"));
+ EXPECT_FALSE(a.endsWith('a'));
+ EXPECT_TRUE(a.removeSuffix(""));
+ EXPECT_EQ("", a);
+ EXPECT_FALSE(a.removeSuffix("a"));
+ EXPECT_EQ("", a);
+ EXPECT_FALSE(a.removeSuffix('a'));
+ EXPECT_EQ("", a);
+}
+
TEST(qfind, UInt32_Ranges) {
vector<uint32_t> a({1, 2, 3, 260, 5});
vector<uint32_t> b({2, 3, 4});
@@ -494,3 +614,4 @@ TYPED_TEST(NeedleFinderTest, NoSegFault) {
}
}
}
+

0 comments on commit c84a6ad

Please sign in to comment.