From: Josh Metzler Date: Tue, 30 Jul 2013 17:36:58 +0000 (-0700) Subject: Use std::equal<> as qfind default comparator X-Git-Tag: v0.22.0~918 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=9ada53a918e2e29c124f1571a609cf3ca98e377d;p=folly.git Use std::equal<> as qfind default comparator Summary: qfind(haystack, needle) is templated, but used a non-templated default comparator that cast everything to char. This works find for 8-bit types, but not for others such as the uint32_t Ranges we are using. Replace the default comparator with std::equal<> to use a working comparator for whatever type is being searched. Test Plan: Compiles, unit tests (including a new one that fails with the old code) pass. Not sure how to test other users of this, or measure performance impact. :( Reviewed By: andrei.alexandrescu@fb.com FB internal diff: D906311 --- diff --git a/folly/Range.h b/folly/Range.h index a1cce77f..b0834b8b 100644 --- a/folly/Range.h +++ b/folly/Range.h @@ -49,9 +49,10 @@ template class Range; * as Boyer-Moore. On the upside, it does not do any upfront * preprocessing and does not allocate memory. */ -template +template ::value_type>> inline size_t qfind(const Range & haystack, - const Range & needle); + const Range & needle, + Comp eq = Comp()); /** * Finds the first occurrence of needle in haystack. The result is the @@ -566,10 +567,10 @@ struct StringPieceHash { /** * Finds substrings faster than brute force by borrowing from Boyer-Moore */ -template +template ::value_type>> size_t qfind(const Range& haystack, const Range& needle, - Comp eq) { + Comp eq = Comp()) { // Don't use std::search, use a Boyer-Moore-like trick by comparing // the last characters first auto const nsize = needle.size(); @@ -673,12 +674,6 @@ struct AsciiCaseInsensitive { extern const AsciiCaseSensitive asciiCaseSensitive; extern const AsciiCaseInsensitive asciiCaseInsensitive; -template -size_t qfind(const Range& haystack, - const Range& needle) { - return qfind(haystack, needle, asciiCaseSensitive); -} - template size_t qfind(const Range& haystack, const typename Range::value_type& needle) { diff --git a/folly/test/RangeTest.cpp b/folly/test/RangeTest.cpp index 1c2b1f36..1ed678c8 100644 --- a/folly/test/RangeTest.cpp +++ b/folly/test/RangeTest.cpp @@ -290,6 +290,19 @@ TEST(StringPiece, InvalidRange) { EXPECT_THROW(a.subpiece(6), std::out_of_range); } +TEST(qfind, UInt32_Ranges) { + vector a({1, 2, 3, 260, 5}); + vector b({2, 3, 4}); + + auto a_range = folly::Range(&a[0], a.size()); + auto b_range = folly::Range(&b[0], b.size()); + + EXPECT_EQ(qfind(a_range, b_range), string::npos); + + a[3] = 4; + EXPECT_EQ(qfind(a_range, b_range), 1); +} + template class NeedleFinderTest : public ::testing::Test { public: