From 35c28f057132fbf1fb5376acf30fafe01a740a02 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Thu, 28 Nov 2024 09:00:31 -0800 Subject: [PATCH] src: use spaceship operator in SocketAddress --- src/node_sockaddr-inl.h | 19 ++--------- src/node_sockaddr.cc | 65 +++++++++++++++++------------------- src/node_sockaddr.h | 17 +++------- test/cctest/test_sockaddr.cc | 24 ++++++------- 4 files changed, 49 insertions(+), 76 deletions(-) diff --git a/src/node_sockaddr-inl.h b/src/node_sockaddr-inl.h index e16a09b04c7d6f..87ff9b62268657 100644 --- a/src/node_sockaddr-inl.h +++ b/src/node_sockaddr-inl.h @@ -172,22 +172,9 @@ bool SocketAddress::operator!=(const SocketAddress& other) const { return !(*this == other); } -bool SocketAddress::operator<(const SocketAddress& other) const { - return compare(other) == CompareResult::LESS_THAN; -} - -bool SocketAddress::operator>(const SocketAddress& other) const { - return compare(other) == CompareResult::GREATER_THAN; -} - -bool SocketAddress::operator<=(const SocketAddress& other) const { - CompareResult c = compare(other); - return c == CompareResult::NOT_COMPARABLE ? false : - c <= CompareResult::SAME; -} - -bool SocketAddress::operator>=(const SocketAddress& other) const { - return compare(other) >= CompareResult::SAME; +std::partial_ordering SocketAddress::operator<=>( + const SocketAddress& other) const { + return compare(other); } template diff --git a/src/node_sockaddr.cc b/src/node_sockaddr.cc index e1572187437f1b..19fcc6b89ac145 100644 --- a/src/node_sockaddr.cc +++ b/src/node_sockaddr.cc @@ -154,9 +154,8 @@ bool is_match_ipv4_ipv6( sizeof(uint32_t)) == 0; } -SocketAddress::CompareResult compare_ipv4( - const SocketAddress& one, - const SocketAddress& two) { +std::partial_ordering compare_ipv4(const SocketAddress& one, + const SocketAddress& two) { const sockaddr_in* one_in = reinterpret_cast(one.data()); const sockaddr_in* two_in = @@ -165,31 +164,29 @@ SocketAddress::CompareResult compare_ipv4( const uint32_t s_addr_two = ntohl(two_in->sin_addr.s_addr); if (s_addr_one < s_addr_two) - return SocketAddress::CompareResult::LESS_THAN; + return std::partial_ordering::less; else if (s_addr_one == s_addr_two) - return SocketAddress::CompareResult::SAME; + return std::partial_ordering::equivalent; else - return SocketAddress::CompareResult::GREATER_THAN; + return std::partial_ordering::greater; } -SocketAddress::CompareResult compare_ipv6( - const SocketAddress& one, - const SocketAddress& two) { +std::partial_ordering compare_ipv6(const SocketAddress& one, + const SocketAddress& two) { const sockaddr_in6* one_in = reinterpret_cast(one.data()); const sockaddr_in6* two_in = reinterpret_cast(two.data()); int ret = memcmp(&one_in->sin6_addr, &two_in->sin6_addr, 16); if (ret < 0) - return SocketAddress::CompareResult::LESS_THAN; + return std::partial_ordering::less; else if (ret > 0) - return SocketAddress::CompareResult::GREATER_THAN; - return SocketAddress::CompareResult::SAME; + return std::partial_ordering::greater; + return std::partial_ordering::equivalent; } -SocketAddress::CompareResult compare_ipv4_ipv6( - const SocketAddress& ipv4, - const SocketAddress& ipv6) { +std::partial_ordering compare_ipv4_ipv6(const SocketAddress& ipv4, + const SocketAddress& ipv6) { const sockaddr_in* ipv4_in = reinterpret_cast(ipv4.data()); const sockaddr_in6 * ipv6_in = @@ -199,7 +196,7 @@ SocketAddress::CompareResult compare_ipv4_ipv6( reinterpret_cast(&ipv6_in->sin6_addr); if (memcmp(ptr, mask, sizeof(mask)) != 0) - return SocketAddress::CompareResult::NOT_COMPARABLE; + return std::partial_ordering::unordered; int ret = memcmp( &ipv4_in->sin_addr, @@ -207,10 +204,10 @@ SocketAddress::CompareResult compare_ipv4_ipv6( sizeof(uint32_t)); if (ret < 0) - return SocketAddress::CompareResult::LESS_THAN; + return std::partial_ordering::less; else if (ret > 0) - return SocketAddress::CompareResult::GREATER_THAN; - return SocketAddress::CompareResult::SAME; + return std::partial_ordering::greater; + return std::partial_ordering::equivalent; } bool in_network_ipv4( @@ -235,7 +232,7 @@ bool in_network_ipv6( // Special case, if prefix == 128, then just do a // straight comparison. if (prefix == 128) - return compare_ipv6(ip, net) == SocketAddress::CompareResult::SAME; + return compare_ipv6(ip, net) == std::partial_ordering::equivalent; uint8_t r = prefix % 8; int len = (prefix - r) / 8; @@ -263,7 +260,7 @@ bool in_network_ipv4_ipv6( int prefix) { if (prefix == 128) - return compare_ipv4_ipv6(ip, net) == SocketAddress::CompareResult::SAME; + return compare_ipv4_ipv6(ip, net) == std::partial_ordering::equivalent; uint8_t r = prefix % 8; int len = (prefix - r) / 8; @@ -293,7 +290,7 @@ bool in_network_ipv6_ipv4( const SocketAddress& net, int prefix) { if (prefix == 32) - return compare_ipv4_ipv6(net, ip) == SocketAddress::CompareResult::SAME; + return compare_ipv4_ipv6(net, ip) == std::partial_ordering::equivalent; uint32_t m = ((1ull << prefix) - 1) << (32 - prefix); @@ -337,8 +334,7 @@ bool SocketAddress::is_match(const SocketAddress& other) const { return false; } -SocketAddress::CompareResult SocketAddress::compare( - const SocketAddress& other) const { +std::partial_ordering SocketAddress::compare(const SocketAddress& other) const { switch (family()) { case AF_INET: switch (other.family()) { @@ -349,16 +345,15 @@ SocketAddress::CompareResult SocketAddress::compare( case AF_INET6: switch (other.family()) { case AF_INET: { - CompareResult c = compare_ipv4_ipv6(other, *this); - switch (c) { - case SocketAddress::CompareResult::NOT_COMPARABLE: - // Fall through - case SocketAddress::CompareResult::SAME: - return c; - case SocketAddress::CompareResult::GREATER_THAN: - return SocketAddress::CompareResult::LESS_THAN; - case SocketAddress::CompareResult::LESS_THAN: - return SocketAddress::CompareResult::GREATER_THAN; + auto c = compare_ipv4_ipv6(other, *this); + if (c == std::partial_ordering::unordered) { + return std::partial_ordering::unordered; + } else if (c == std::partial_ordering::equivalent) { + return std::partial_ordering::equivalent; + } else if (c == std::partial_ordering::less) { + return std::partial_ordering::greater; + } else if (c == std::partial_ordering::greater) { + return std::partial_ordering::less; } break; } @@ -366,7 +361,7 @@ SocketAddress::CompareResult SocketAddress::compare( } break; } - return SocketAddress::CompareResult::NOT_COMPARABLE; + return std::partial_ordering::unordered; } bool SocketAddress::is_in_network( diff --git a/src/node_sockaddr.h b/src/node_sockaddr.h index 84aa3adf5fc72a..b822e186969917 100644 --- a/src/node_sockaddr.h +++ b/src/node_sockaddr.h @@ -11,9 +11,10 @@ #include "uv.h" #include "v8.h" +#include +#include #include #include -#include #include namespace node { @@ -22,13 +23,6 @@ class Environment; class SocketAddress : public MemoryRetainer { public: - enum class CompareResult { - NOT_COMPARABLE = -2, - LESS_THAN, - SAME, - GREATER_THAN - }; - struct Hash { size_t operator()(const SocketAddress& addr) const; }; @@ -36,10 +30,7 @@ class SocketAddress : public MemoryRetainer { inline bool operator==(const SocketAddress& other) const; inline bool operator!=(const SocketAddress& other) const; - inline bool operator<(const SocketAddress& other) const; - inline bool operator>(const SocketAddress& other) const; - inline bool operator<=(const SocketAddress& other) const; - inline bool operator>=(const SocketAddress& other) const; + inline std::partial_ordering operator<=>(const SocketAddress& other) const; inline static bool is_numeric_host(const char* hostname); inline static bool is_numeric_host(const char* hostname, int family); @@ -102,7 +93,7 @@ class SocketAddress : public MemoryRetainer { bool is_match(const SocketAddress& other) const; // Compares this SocketAddress to the given other SocketAddress. - CompareResult compare(const SocketAddress& other) const; + std::partial_ordering compare(const SocketAddress& other) const; // Returns true if this SocketAddress is within the subnet // identified by the given network address and CIDR prefix. diff --git a/test/cctest/test_sockaddr.cc b/test/cctest/test_sockaddr.cc index bd80d59f821e5d..68b8739f97e1fc 100644 --- a/test/cctest/test_sockaddr.cc +++ b/test/cctest/test_sockaddr.cc @@ -145,9 +145,9 @@ TEST(SocketAddress, Comparison) { SocketAddress addr5(reinterpret_cast(&storage[4])); SocketAddress addr6(reinterpret_cast(&storage[5])); - CHECK_EQ(addr1.compare(addr1), SocketAddress::CompareResult::SAME); - CHECK_EQ(addr1.compare(addr2), SocketAddress::CompareResult::LESS_THAN); - CHECK_EQ(addr2.compare(addr1), SocketAddress::CompareResult::GREATER_THAN); + CHECK_EQ(addr1.compare(addr1), std::partial_ordering::equivalent); + CHECK_EQ(addr1.compare(addr2), std::partial_ordering::less); + CHECK_EQ(addr2.compare(addr1), std::partial_ordering::greater); CHECK(addr1 <= addr1); CHECK(addr1 < addr2); CHECK(addr1 <= addr2); @@ -155,9 +155,9 @@ TEST(SocketAddress, Comparison) { CHECK(addr2 > addr1); CHECK(addr2 >= addr1); - CHECK_EQ(addr3.compare(addr3), SocketAddress::CompareResult::SAME); - CHECK_EQ(addr3.compare(addr4), SocketAddress::CompareResult::LESS_THAN); - CHECK_EQ(addr4.compare(addr3), SocketAddress::CompareResult::GREATER_THAN); + CHECK_EQ(addr3.compare(addr3), std::partial_ordering::equivalent); + CHECK_EQ(addr3.compare(addr4), std::partial_ordering::less); + CHECK_EQ(addr4.compare(addr3), std::partial_ordering::greater); CHECK(addr3 <= addr3); CHECK(addr3 < addr4); CHECK(addr3 <= addr4); @@ -166,8 +166,8 @@ TEST(SocketAddress, Comparison) { CHECK(addr4 >= addr3); // Not comparable - CHECK_EQ(addr1.compare(addr3), SocketAddress::CompareResult::NOT_COMPARABLE); - CHECK_EQ(addr3.compare(addr1), SocketAddress::CompareResult::NOT_COMPARABLE); + CHECK_EQ(addr1.compare(addr3), std::partial_ordering::unordered); + CHECK_EQ(addr3.compare(addr1), std::partial_ordering::unordered); CHECK(!(addr1 < addr3)); CHECK(!(addr1 > addr3)); CHECK(!(addr1 >= addr3)); @@ -178,10 +178,10 @@ TEST(SocketAddress, Comparison) { CHECK(!(addr3 <= addr1)); // Comparable - CHECK_EQ(addr1.compare(addr5), SocketAddress::CompareResult::SAME); - CHECK_EQ(addr2.compare(addr6), SocketAddress::CompareResult::SAME); - CHECK_EQ(addr1.compare(addr6), SocketAddress::CompareResult::LESS_THAN); - CHECK_EQ(addr6.compare(addr1), SocketAddress::CompareResult::GREATER_THAN); + CHECK_EQ(addr1.compare(addr5), std::partial_ordering::equivalent); + CHECK_EQ(addr2.compare(addr6), std::partial_ordering::equivalent); + CHECK_EQ(addr1.compare(addr6), std::partial_ordering::less); + CHECK_EQ(addr6.compare(addr1), std::partial_ordering::greater); CHECK(addr1 <= addr5); CHECK(addr1 <= addr6); CHECK(addr1 < addr6);