Implement StringRef comparison operators

and use lexicographical comparison (#183)
This commit is contained in:
vitaut 2015-10-22 08:41:42 -07:00
parent fb27723a9f
commit f080b62047
2 changed files with 46 additions and 4 deletions

View File

@ -287,15 +287,30 @@ class BasicStringRef {
/** Returns the string size. */
std::size_t size() const { return size_; }
// Lexicographically compare this string reference to other.
int compare(BasicStringRef other) const {
std::size_t size = std::min(size_, other.size_);
int result = std::char_traits<Char>::compare(data_, other.data_, size);
return result != 0 ? result : size_ - other.size_;
}
friend bool operator==(BasicStringRef lhs, BasicStringRef rhs) {
return lhs.data_ == rhs.data_;
return lhs.compare(rhs) == 0;
}
friend bool operator!=(BasicStringRef lhs, BasicStringRef rhs) {
return lhs.data_ != rhs.data_;
return lhs.compare(rhs) != 0;
}
friend bool operator<(BasicStringRef lhs, BasicStringRef rhs) {
return std::lexicographical_compare(
lhs.data_, lhs.data_ + lhs.size_, rhs.data_, rhs.data_ + rhs.size_);
return lhs.compare(rhs) < 0;
}
friend bool operator<=(BasicStringRef lhs, BasicStringRef rhs) {
return lhs.compare(rhs) <= 0;
}
friend bool operator>(BasicStringRef lhs, BasicStringRef rhs) {
return lhs.compare(rhs) > 0;
}
friend bool operator>=(BasicStringRef lhs, BasicStringRef rhs) {
return lhs.compare(rhs) >= 0;
}
};

View File

@ -705,6 +705,33 @@ TEST(UtilTest, StringRef) {
EXPECT_LT(std::strlen(str), sizeof(str));
}
// Check StringRef's comparison operator.
template <template <typename> class Op>
void CheckOp() {
const char *inputs[] = {"foo", "fop", "fo"};
std::size_t num_inputs = sizeof(inputs) / sizeof(*inputs);
for (std::size_t i = 0; i < num_inputs; ++i) {
for (std::size_t j = 0; j < num_inputs; ++j) {
StringRef lhs(inputs[i]), rhs(inputs[j]);
EXPECT_EQ(Op<int>()(lhs.compare(rhs), 0), Op<StringRef>()(lhs, rhs));
}
}
}
TEST(UtilTest, StringRefCompare) {
EXPECT_EQ(0, StringRef("foo").compare(StringRef("foo")));
EXPECT_EQ(1, StringRef("fop").compare(StringRef("foo")));
EXPECT_EQ(-1, StringRef("foo").compare(StringRef("fop")));
EXPECT_EQ(1, StringRef("foo").compare(StringRef("fo")));
EXPECT_EQ(-1, StringRef("fo").compare(StringRef("foo")));
CheckOp<std::equal_to>();
CheckOp<std::not_equal_to>();
CheckOp<std::less>();
CheckOp<std::less_equal>();
CheckOp<std::greater>();
CheckOp<std::greater_equal>();
}
TEST(UtilTest, CountDigits) {
test_count_digits<uint32_t>();
test_count_digits<uint64_t>();