Commit 1408e9d5 authored by Tom Jackson's avatar Tom Jackson Committed by Sara Golemon

Range<T>::rfind()

Test Plan: Unit tests

Reviewed By: andrei.alexandrescu@fb.com

FB internal diff: D865951
parent 8b260639
......@@ -62,6 +62,15 @@ template <class T>
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
......@@ -392,6 +401,10 @@ public:
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);
......@@ -673,6 +686,17 @@ size_t qfind(const Range<T>& haystack,
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) {
......@@ -681,6 +705,13 @@ 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,
......@@ -690,6 +721,14 @@ 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) {
......
......@@ -121,6 +121,16 @@ TEST(StringPiece, All) {
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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment