X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2FRange.h;h=9c9b68b26514712568ab2d1579dbdc5e63beeee3;hb=a0c640e8e2ff45bc43b9f8d96cd108bb66635bee;hp=bfbb4eb0f609c0547da193f3f0875a36f36219cd;hpb=60b6e844c5c581d9e8004e20a3409b6b4430fd9d;p=folly.git diff --git a/folly/Range.h b/folly/Range.h index bfbb4eb0..9c9b68b2 100644 --- a/folly/Range.h +++ b/folly/Range.h @@ -61,7 +61,7 @@ namespace folly { -template class Range; +template class Range; /** * Finds the first occurrence of needle in haystack. The algorithm is on @@ -69,9 +69,10 @@ template class Range; * as Boyer-Moore. On the upside, it does not do any upfront * preprocessing and does not allocate memory. */ -template ::value_type>> -inline size_t qfind(const Range & haystack, - const Range & needle, +template ::value_type>> +inline size_t qfind(const Range & haystack, + const Range & needle, Comp eq = Comp()); /** @@ -79,27 +80,27 @@ inline size_t qfind(const Range & haystack, * offset reported to the beginning of haystack, or string::npos if * needle wasn't found. */ -template -size_t qfind(const Range & haystack, - const typename Range::value_type& needle); +template +size_t qfind(const Range & haystack, + const typename Range::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 -size_t rfind(const Range & haystack, - const typename Range::value_type& needle); +template +size_t rfind(const Range & haystack, + const typename Range::value_type& needle); /** * Finds the first occurrence of any element of needle in * haystack. The algorithm is O(haystack.size() * needle.size()). */ -template -inline size_t qfind_first_of(const Range & haystack, - const Range & needle); +template +inline size_t qfind_first_of(const Range & haystack, + const Range & needle); /** * Small internal helper - returns the value just before an iterator. @@ -205,9 +206,7 @@ public: constexpr Range(Iter start, size_t size) : b_(start), e_(start + size) { } -# if !__clang__ || __CLANG_PREREQ(3, 7) // Clang 3.6 crashes on this line /* implicit */ Range(std::nullptr_t) = delete; -# endif template ::type = 0> constexpr /* implicit */ Range(Iter str) @@ -659,6 +658,16 @@ public: return !empty() && front() == c; } + template + bool startsWith(const const_range_type& other, Comp&& eq) const { + if (size() < other.size()) { + return false; + } + auto const trunc = subpiece(0, other.size()); + return std::equal( + trunc.begin(), trunc.end(), other.begin(), std::forward(eq)); + } + /** * Does this Range end with another range? */ @@ -670,6 +679,16 @@ public: return !empty() && back() == c; } + template + bool endsWith(const const_range_type& other, Comp&& eq) const { + if (size() < other.size()) { + return false; + } + auto const trunc = subpiece(size() - other.size()); + return std::equal( + trunc.begin(), trunc.end(), other.begin(), std::forward(eq)); + } + /** * Remove the items in [b, e), as long as this subrange is at the beginning * or end of the Range. @@ -900,8 +919,8 @@ private: template const typename Range::size_type Range::npos = std::string::npos; -template -void swap(Range& lhs, Range& rhs) { +template +void swap(Range& lhs, Range& rhs) { lhs.swap(rhs); } @@ -956,13 +975,13 @@ inline std::ostream& operator<<(std::ostream& os, * Templated comparison operators */ -template -inline bool operator==(const Range& lhs, const Range& rhs) { +template +inline bool operator==(const Range& lhs, const Range& rhs) { return lhs.size() == rhs.size() && lhs.compare(rhs) == 0; } -template -inline bool operator<(const Range& lhs, const Range& rhs) { +template +inline bool operator<(const Range& lhs, const Range& rhs) { return lhs.compare(rhs) < 0; } @@ -1039,9 +1058,9 @@ operator>=(const T& lhs, const U& rhs) { /** * Finds substrings faster than brute force by borrowing from Boyer-Moore */ -template -size_t qfind(const Range& haystack, - const Range& needle, +template +size_t qfind(const Range& haystack, + const Range& needle, Comp eq) { // Don't use std::search, use a Boyer-Moore-like trick by comparing // the last characters first @@ -1107,9 +1126,9 @@ inline size_t qfind_first_byte_of(const StringPiece haystack, } // namespace detail -template -size_t qfind_first_of(const Range & haystack, - const Range & needles, +template +size_t qfind_first_of(const Range & haystack, + const Range & needles, Comp eq) { auto ret = std::find_first_of(haystack.begin(), haystack.end(), needles.begin(), needles.end(), @@ -1138,16 +1157,16 @@ struct AsciiCaseInsensitive { } }; -template -size_t qfind(const Range& haystack, - const typename Range::value_type& needle) { +template +size_t qfind(const Range& haystack, + const typename Range::value_type& needle) { auto pos = std::find(haystack.begin(), haystack.end(), needle); return pos == haystack.end() ? std::string::npos : pos - haystack.data(); } -template -size_t rfind(const Range& haystack, - const typename Range::value_type& needle) { +template +size_t rfind(const Range& haystack, + const typename Range::value_type& needle) { for (auto i = haystack.size(); i-- > 0; ) { if (haystack[i] == needle) { return i; @@ -1204,9 +1223,9 @@ inline size_t rfind(const Range& haystack, return pos == nullptr ? std::string::npos : pos - haystack.data(); } -template -size_t qfind_first_of(const Range& haystack, - const Range& needles) { +template +size_t qfind_first_of(const Range& haystack, + const Range& needles) { return qfind_first_of(haystack, needles, AsciiCaseSensitive()); }