Commit 9a83e424 authored by Giuseppe Ottaviano's avatar Giuseppe Ottaviano Committed by Facebook GitHub Bot

De-template Range comparison operators

Summary:
The `StringPiece` overloads of comparisons operators are inefficient to compile, as they get in the overload set of every comparison and then get ruled out by SFINAE (which require trait instantiations).

Move them instead to friend inlines, where they enjoy the expected implicit conversion rules.

(Note: this ignores all push blocking failures!)

Reviewed By: yfeldblum

Differential Revision: D25549986

fbshipit-source-id: fd323e2e8cbf4f3dd29508b8aff1cfaba2784f4f
parent acef4a64
......@@ -1066,6 +1066,30 @@ class Range {
return process(split_step(delimiter), std::forward<Args>(args)...);
}
friend bool operator==(const Range& lhs, const Range& rhs) {
return lhs.size() == rhs.size() && lhs.compare(rhs) == 0;
}
friend bool operator!=(const Range& lhs, const Range& rhs) {
return !(operator==(lhs, rhs));
}
friend bool operator<(const Range& lhs, const Range& rhs) {
return lhs.compare(rhs) < 0;
}
friend bool operator<=(const Range& lhs, const Range& rhs) {
return lhs.compare(rhs) <= 0;
}
friend bool operator>(const Range& lhs, const Range& rhs) {
return lhs.compare(rhs) > 0;
}
friend bool operator>=(const Range& lhs, const Range& rhs) {
return lhs.compare(rhs) >= 0;
}
private:
Iter b_;
Iter e_;
......@@ -1151,118 +1175,6 @@ std::basic_ostream<C>& operator<<(std::basic_ostream<C>& os, Range<C*> piece) {
return os;
}
/**
* Templated comparison operators
*/
template <class Iter>
inline bool operator==(const Range<Iter>& lhs, const Range<Iter>& rhs) {
return lhs.size() == rhs.size() && lhs.compare(rhs) == 0;
}
template <class Iter>
inline bool operator!=(const Range<Iter>& lhs, const Range<Iter>& rhs) {
return !(operator==(lhs, rhs));
}
template <class Iter>
inline bool operator<(const Range<Iter>& lhs, const Range<Iter>& rhs) {
return lhs.compare(rhs) < 0;
}
template <class Iter>
inline bool operator<=(const Range<Iter>& lhs, const Range<Iter>& rhs) {
return lhs.compare(rhs) <= 0;
}
template <class Iter>
inline bool operator>(const Range<Iter>& lhs, const Range<Iter>& rhs) {
return lhs.compare(rhs) > 0;
}
template <class Iter>
inline bool operator>=(const Range<Iter>& lhs, const Range<Iter>& rhs) {
return lhs.compare(rhs) >= 0;
}
/**
* Specializations of comparison operators for StringPiece
*/
namespace detail {
template <class A, class B>
struct ComparableAsStringPiece {
enum {
value = (std::is_convertible<A, StringPiece>::value &&
std::is_same<B, StringPiece>::value) ||
(std::is_convertible<B, StringPiece>::value &&
std::is_same<A, StringPiece>::value)
};
};
} // namespace detail
/**
* operator== through conversion for Range<const char*>
*/
template <class T, class U>
std::enable_if_t<detail::ComparableAsStringPiece<T, U>::value, bool> operator==(
const T& lhs,
const U& rhs) {
return StringPiece(lhs) == StringPiece(rhs);
}
/**
* operator!= through conversion for Range<const char*>
*/
template <class T, class U>
std::enable_if_t<detail::ComparableAsStringPiece<T, U>::value, bool> operator!=(
const T& lhs,
const U& rhs) {
return StringPiece(lhs) != StringPiece(rhs);
}
/**
* operator< through conversion for Range<const char*>
*/
template <class T, class U>
std::enable_if_t<detail::ComparableAsStringPiece<T, U>::value, bool> operator<(
const T& lhs,
const U& rhs) {
return StringPiece(lhs) < StringPiece(rhs);
}
/**
* operator> through conversion for Range<const char*>
*/
template <class T, class U>
std::enable_if_t<detail::ComparableAsStringPiece<T, U>::value, bool> operator>(
const T& lhs,
const U& rhs) {
return StringPiece(lhs) > StringPiece(rhs);
}
/**
* operator< through conversion for Range<const char*>
*/
template <class T, class U>
std::enable_if_t<detail::ComparableAsStringPiece<T, U>::value, bool> operator<=(
const T& lhs,
const U& rhs) {
return StringPiece(lhs) <= StringPiece(rhs);
}
/**
* operator> through conversion for Range<const char*>
*/
template <class T, class U>
std::enable_if_t<detail::ComparableAsStringPiece<T, U>::value, bool> operator>=(
const T& lhs,
const U& rhs) {
return StringPiece(lhs) >= StringPiece(rhs);
}
/**
* Finds substrings faster than brute force by borrowing from Boyer-Moore
*/
......
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