size_t qfind(const Range<T> & haystack,
const typename Range<T>::value_type& needle);
+/**
+ * Finds the last occurrence of needle in haystack. The result is the
+ * offset reported to the beginning of haystack, or string::npos if
+ * needle wasn't found.
+ */
+template <class T>
+size_t rfind(const Range<T> & haystack,
+ const typename Range<T>::value_type& needle);
+
/**
* Finds the first occurrence of any element of needle in
return qfind(*this, c);
}
+ size_type rfind(value_type c) const {
+ return folly::rfind(*this, c);
+ }
+
size_type find(value_type c, size_t pos) const {
if (pos > size()) return std::string::npos;
size_type ret = qfind(subpiece(pos), c);
return pos == haystack.end() ? std::string::npos : pos - haystack.data();
}
+template <class T>
+size_t rfind(const Range<T>& haystack,
+ const typename Range<T>::value_type& needle) {
+ for (auto i = haystack.size(); i-- > 0; ) {
+ if (haystack[i] == needle) {
+ return i;
+ }
+ }
+ return std::string::npos;
+}
+
// specialization for StringPiece
template <>
inline size_t qfind(const Range<const char*>& haystack, const char& needle) {
return pos == nullptr ? std::string::npos : pos - haystack.data();
}
+template <>
+inline size_t rfind(const Range<const char*>& haystack, const char& needle) {
+ auto pos = static_cast<const char*>(
+ ::memrchr(haystack.data(), needle, haystack.size()));
+ return pos == nullptr ? std::string::npos : pos - haystack.data();
+}
+
// specialization for ByteRange
template <>
inline size_t qfind(const Range<const unsigned char*>& haystack,
return pos == nullptr ? std::string::npos : pos - haystack.data();
}
+template <>
+inline size_t rfind(const Range<const unsigned char*>& haystack,
+ const unsigned char& needle) {
+ auto pos = static_cast<const unsigned char*>(
+ ::memrchr(haystack.data(), needle, haystack.size()));
+ return pos == nullptr ? std::string::npos : pos - haystack.data();
+}
+
template <class T>
size_t qfind_first_of(const Range<T>& haystack,
const Range<T>& needles) {
EXPECT_EQ(s.find('\0'), std::string().find('\0'));
EXPECT_EQ(s.find('\0'), StringPiece::npos);
+ // single char rfinds
+ EXPECT_EQ(s.rfind('b'), 6);
+ EXPECT_EQ(s.rfind('y'), StringPiece::npos);
+ EXPECT_EQ(s.str().rfind('y'), StringPiece::npos);
+ EXPECT_EQ(ByteRange(s).rfind('b'), 6);
+ EXPECT_EQ(ByteRange(s).rfind('y'), StringPiece::npos);
+ // null char
+ EXPECT_EQ(s.rfind('\0'), s.str().rfind('\0'));
+ EXPECT_EQ(s.rfind('\0'), StringPiece::npos);
+
// find_first_of
s.reset(foobarbaz, strlen(foobarbaz));
EXPECT_EQ(s.find_first_of("bar"), 3);