diff options
author | Mathias Stearn <redbeard0531@gmail.com> | 2022-03-16 15:06:48 +0100 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-03-18 17:22:58 +0000 |
commit | b6688d9a44715e1472c1204c069b635325727715 (patch) | |
tree | 0bbf0f601c50b245a74392b197c868546071b31d /src/mongo | |
parent | ff9ab764ccd4249dc929858a02d88a0e1cac16fd (diff) | |
download | mongo-b6688d9a44715e1472c1204c069b635325727715.tar.gz |
SERVER-64553 make StringData comparisons constexpr
Diffstat (limited to 'src/mongo')
-rw-r--r-- | src/mongo/base/string_data.h | 27 | ||||
-rw-r--r-- | src/mongo/base/string_data_test.cpp | 8 |
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) { |