summaryrefslogtreecommitdiff
path: root/src/mongo/base
diff options
context:
space:
mode:
authorMathias Stearn <redbeard0531@gmail.com>2022-03-16 15:06:48 +0100
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-03-18 17:22:58 +0000
commitb6688d9a44715e1472c1204c069b635325727715 (patch)
tree0bbf0f601c50b245a74392b197c868546071b31d /src/mongo/base
parentff9ab764ccd4249dc929858a02d88a0e1cac16fd (diff)
downloadmongo-b6688d9a44715e1472c1204c069b635325727715.tar.gz
SERVER-64553 make StringData comparisons constexpr
Diffstat (limited to 'src/mongo/base')
-rw-r--r--src/mongo/base/string_data.h27
-rw-r--r--src/mongo/base/string_data_test.cpp8
2 files changed, 18 insertions, 17 deletions
diff --git a/src/mongo/base/string_data.h b/src/mongo/base/string_data.h
index c040c98cfb5..eeda23aa3e9 100644
--- a/src/mongo/base/string_data.h
+++ b/src/mongo/base/string_data.h
@@ -121,7 +121,7 @@ public:
* Returns -1, 0, or 1 if 'this' is less, equal, or greater than 'other' in
* lexicographical order.
*/
- int compare(StringData other) const;
+ constexpr int compare(StringData other) const;
/**
* note: this uses tolower, and therefore does not handle
@@ -193,42 +193,35 @@ private:
size_t _size = 0; // 'size' does not include the null terminator
};
-inline bool operator==(StringData lhs, StringData rhs) {
+constexpr bool operator==(StringData lhs, StringData rhs) {
return (lhs.size() == rhs.size()) && (lhs.compare(rhs) == 0);
}
-inline bool operator!=(StringData lhs, StringData rhs) {
+constexpr bool operator!=(StringData lhs, StringData rhs) {
return !(lhs == rhs);
}
-inline bool operator<(StringData lhs, StringData rhs) {
+constexpr bool operator<(StringData lhs, StringData rhs) {
return lhs.compare(rhs) < 0;
}
-inline bool operator<=(StringData lhs, StringData rhs) {
+constexpr bool operator<=(StringData lhs, StringData rhs) {
return lhs.compare(rhs) <= 0;
}
-inline bool operator>(StringData lhs, StringData rhs) {
+constexpr bool operator>(StringData lhs, StringData rhs) {
return lhs.compare(rhs) > 0;
}
-inline bool operator>=(StringData lhs, StringData rhs) {
+constexpr bool operator>=(StringData lhs, StringData rhs) {
return lhs.compare(rhs) >= 0;
}
std::ostream& operator<<(std::ostream& stream, StringData value);
-inline int StringData::compare(StringData other) const {
- // It is illegal to pass nullptr to memcmp. It is an invariant of
- // StringData that if _data is nullptr, _size is zero. If asked to
- // compare zero bytes, memcmp returns zero (how could they
- // differ?). So, if either StringData object has a nullptr _data
- // object, then memcmp would return zero. Achieve this by assuming
- // zero, and only calling memcmp if both pointers are valid.
- int res = 0;
- if (_data && other._data)
- res = memcmp(_data, other._data, std::min(_size, other._size));
+constexpr int StringData::compare(StringData other) const {
+ // Note: char_traits::compare() allows nullptr arguments unlike memcmp().
+ int res = std::char_traits<char>::compare(_data, other._data, std::min(_size, other._size));
if (res != 0)
return res > 0 ? 1 : -1;
diff --git a/src/mongo/base/string_data_test.cpp b/src/mongo/base/string_data_test.cpp
index a809ddf8f95..ee05394bfde 100644
--- a/src/mongo/base/string_data_test.cpp
+++ b/src/mongo/base/string_data_test.cpp
@@ -127,6 +127,8 @@ TEST(Comparison, BothEmpty) {
ASSERT_TRUE(empty >= empty);
ASSERT_FALSE(empty < empty);
ASSERT_TRUE(empty <= empty);
+
+ static_assert(""_sd.compare(""_sd) == 0);
}
TEST(Comparison, BothNonEmptyOnSize) {
@@ -140,6 +142,8 @@ TEST(Comparison, BothNonEmptyOnSize) {
ASSERT_TRUE(a < aa);
ASSERT_TRUE(a <= aa);
ASSERT_TRUE(a <= a);
+
+ static_assert("a"_sd.compare("aa"_sd) < 0);
}
TEST(Comparison, BothNonEmptyOnContent) {
@@ -151,6 +155,8 @@ TEST(Comparison, BothNonEmptyOnContent) {
ASSERT_FALSE(a >= b);
ASSERT_TRUE(a < b);
ASSERT_TRUE(a <= b);
+
+ static_assert("a"_sd.compare("b"_sd) < 0);
}
TEST(Comparison, MixedEmptyAndNot) {
@@ -162,6 +168,8 @@ TEST(Comparison, MixedEmptyAndNot) {
ASSERT_TRUE(a >= empty);
ASSERT_FALSE(a < empty);
ASSERT_FALSE(a <= empty);
+
+ static_assert(""_sd.compare("a"_sd) < 0);
}
TEST(Find, Char1) {