src: use spaceship operator in SocketAddress

PR-URL: https://github.com/nodejs/node/pull/56059
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
This commit is contained in:
James M Snell 2024-11-28 09:00:31 -08:00
parent 3b6da7ce76
commit b915124e49
4 changed files with 49 additions and 76 deletions

View file

@ -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 <typename T>

View file

@ -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<const sockaddr_in*>(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<const sockaddr_in6*>(one.data());
const sockaddr_in6* two_in =
reinterpret_cast<const sockaddr_in6*>(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<const sockaddr_in*>(ipv4.data());
const sockaddr_in6 * ipv6_in =
@ -199,7 +196,7 @@ SocketAddress::CompareResult compare_ipv4_ipv6(
reinterpret_cast<const uint8_t*>(&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(

View file

@ -11,9 +11,10 @@
#include "uv.h"
#include "v8.h"
#include <compare>
#include <list>
#include <memory>
#include <string>
#include <list>
#include <unordered_map>
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.

View file

@ -145,9 +145,9 @@ TEST(SocketAddress, Comparison) {
SocketAddress addr5(reinterpret_cast<const sockaddr*>(&storage[4]));
SocketAddress addr6(reinterpret_cast<const sockaddr*>(&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);