/*
- * Copyright 2012 Facebook, Inc.
+ * Copyright 2013 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits.hpp>
#include <bits/c++config.h>
+#include "folly/CpuId.h"
#include "folly/Traits.h"
namespace folly {
Range() : b_(), e_() {
}
-private:
- static bool reachable(Iter b, Iter e, std::forward_iterator_tag) {
- for (; b != e; ++b) {
- LOG_EVERY_N(INFO, 100000) << __FILE__ ":" << __LINE__
- << " running reachability test ("
- << google::COUNTER << " iterations)...";
- }
- return true;
- }
-
- static bool reachable(Iter b, Iter e, std::random_access_iterator_tag) {
- return b <= e;
- }
-
public:
// Works for all iterators
- Range(Iter start, Iter end)
- : b_(start), e_(end) {
- assert(reachable(b_, e_,
- typename std::iterator_traits<Iter>::iterator_category()));
+ Range(Iter start, Iter end) : b_(start), e_(end) {
}
// Works only for random-access iterators
return std::string::npos;
}
+namespace detail {
+
+size_t qfind_first_byte_of_nosse(const StringPiece& haystack,
+ const StringPiece& needles);
+
+#if FOLLY_HAVE_EMMINTRIN_H
+size_t qfind_first_byte_of_sse42(const StringPiece& haystack,
+ const StringPiece& needles);
+
+inline size_t qfind_first_byte_of(const StringPiece& haystack,
+ const StringPiece& needles) {
+ static auto const qfind_first_byte_of_fn =
+ folly::CpuId().sse42() ? qfind_first_byte_of_sse42
+ : qfind_first_byte_of_nosse;
+ return qfind_first_byte_of_fn(haystack, needles);
+}
+
+#else
+inline size_t qfind_first_byte_of(const StringPiece& haystack,
+ const StringPiece& needles) {
+ return qfind_first_byte_of_nosse(haystack, needles);
+}
+#endif // FOLLY_HAVE_EMMINTRIN_H
+
+} // namespace detail
+
template <class T, class Comp>
size_t qfind_first_of(const Range<T> & haystack,
- const Range<T> & needle,
+ const Range<T> & needles,
Comp eq) {
auto ret = std::find_first_of(haystack.begin(), haystack.end(),
- needle.begin(), needle.end(),
+ needles.begin(), needles.end(),
eq);
return ret == haystack.end() ? std::string::npos : ret - haystack.begin();
}
template <class T>
size_t qfind_first_of(const Range<T>& haystack,
- const Range<T>& needle) {
- return qfind_first_of(haystack, needle, asciiCaseSensitive);
+ const Range<T>& needles) {
+ return qfind_first_of(haystack, needles, asciiCaseSensitive);
}
+// specialization for StringPiece
+template <>
+inline size_t qfind_first_of(const Range<const char*>& haystack,
+ const Range<const char*>& needles) {
+ return detail::qfind_first_byte_of(haystack, needles);
+}
+
+// specialization for ByteRange
+template <>
+inline size_t qfind_first_of(const Range<const unsigned char*>& haystack,
+ const Range<const unsigned char*>& needles) {
+ return detail::qfind_first_byte_of(StringPiece(haystack),
+ StringPiece(needles));
+}
} // !namespace folly
FOLLY_ASSUME_FBVECTOR_COMPATIBLE_1(folly::Range);