Commit 9ada53a9 authored by Josh Metzler's avatar Josh Metzler Committed by Sara Golemon

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
parent b22d95e4
......@@ -49,9 +49,10 @@ template <class T> class Range;
* as Boyer-Moore. On the upside, it does not do any upfront
* preprocessing and does not allocate memory.
*/
template <class T>
template <class T, class Comp = std::equal_to<typename Range<T>::value_type>>
inline size_t qfind(const Range<T> & haystack,
const Range<T> & needle);
const Range<T> & 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 <class T, class Comp>
template <class T, class Comp = std::equal_to<typename Range<T>::value_type>>
size_t qfind(const Range<T>& haystack,
const Range<T>& 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 <class T>
size_t qfind(const Range<T>& haystack,
const Range<T>& needle) {
return qfind(haystack, needle, asciiCaseSensitive);
}
template <class T>
size_t qfind(const Range<T>& haystack,
const typename Range<T>::value_type& needle) {
......
......@@ -290,6 +290,19 @@ TEST(StringPiece, InvalidRange) {
EXPECT_THROW(a.subpiece(6), std::out_of_range);
}
TEST(qfind, UInt32_Ranges) {
vector<uint32_t> a({1, 2, 3, 260, 5});
vector<uint32_t> b({2, 3, 4});
auto a_range = folly::Range<const uint32_t*>(&a[0], a.size());
auto b_range = folly::Range<const uint32_t*>(&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 <typename NeedleFinder>
class NeedleFinderTest : public ::testing::Test {
public:
......
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