mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-05 08:47:53 +00:00
Use <=> operator for base_uint, Issue, and Book: (#4411)
- Implement the `operator==` and the `operator<=>` (aka the spaceship operator) in `base_uint`, `Issue`, and `Book`. - C++20-compliant compilers automatically provide the remaining comparison operators (e.g. `operator<`, `operator<=`, ...). - Remove the function compare() because it is no longer needed. - Maintain the same semantics as the existing code. - Add some unit tests to gain further confidence. - Fix #2525.
This commit is contained in:
@@ -33,6 +33,7 @@
|
||||
#include <ripple/beast/utility/Zero.h>
|
||||
#include <boost/endian/conversion.hpp>
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
@@ -549,103 +550,66 @@ using uint160 = base_uint<160>;
|
||||
using uint256 = base_uint<256>;
|
||||
|
||||
template <std::size_t Bits, class Tag>
|
||||
inline int
|
||||
compare(base_uint<Bits, Tag> const& a, base_uint<Bits, Tag> const& b)
|
||||
[[nodiscard]] inline constexpr std::strong_ordering
|
||||
operator<=>(base_uint<Bits, Tag> const& lhs, base_uint<Bits, Tag> const& rhs)
|
||||
{
|
||||
auto ret = std::mismatch(a.cbegin(), a.cend(), b.cbegin());
|
||||
// This comparison might seem wrong on a casual inspection because it
|
||||
// compares data internally stored as std::uint32_t byte-by-byte. But
|
||||
// note that the underlying data is stored in big endian, even if the
|
||||
// plaform is little endian. This makes the comparison correct.
|
||||
//
|
||||
// FIXME: use std::lexicographical_compare_three_way once support is
|
||||
// added to MacOS.
|
||||
|
||||
if (ret.first == a.cend())
|
||||
return 0;
|
||||
auto const ret = std::mismatch(lhs.cbegin(), lhs.cend(), rhs.cbegin());
|
||||
|
||||
// a > b
|
||||
if (*ret.first > *ret.second)
|
||||
return 1;
|
||||
// a == b
|
||||
if (ret.first == lhs.cend())
|
||||
return std::strong_ordering::equivalent;
|
||||
|
||||
// a < b
|
||||
return -1;
|
||||
return (*ret.first > *ret.second) ? std::strong_ordering::greater
|
||||
: std::strong_ordering::less;
|
||||
}
|
||||
|
||||
template <std::size_t Bits, class Tag>
|
||||
inline bool
|
||||
operator<(base_uint<Bits, Tag> const& a, base_uint<Bits, Tag> const& b)
|
||||
template <std::size_t Bits, typename Tag>
|
||||
[[nodiscard]] inline constexpr bool
|
||||
operator==(base_uint<Bits, Tag> const& lhs, base_uint<Bits, Tag> const& rhs)
|
||||
{
|
||||
return compare(a, b) < 0;
|
||||
}
|
||||
|
||||
template <std::size_t Bits, class Tag>
|
||||
inline bool
|
||||
operator<=(base_uint<Bits, Tag> const& a, base_uint<Bits, Tag> const& b)
|
||||
{
|
||||
return compare(a, b) <= 0;
|
||||
}
|
||||
|
||||
template <std::size_t Bits, class Tag>
|
||||
inline bool
|
||||
operator>(base_uint<Bits, Tag> const& a, base_uint<Bits, Tag> const& b)
|
||||
{
|
||||
return compare(a, b) > 0;
|
||||
}
|
||||
|
||||
template <std::size_t Bits, class Tag>
|
||||
inline bool
|
||||
operator>=(base_uint<Bits, Tag> const& a, base_uint<Bits, Tag> const& b)
|
||||
{
|
||||
return compare(a, b) >= 0;
|
||||
}
|
||||
|
||||
template <std::size_t Bits, class Tag>
|
||||
inline bool
|
||||
operator==(base_uint<Bits, Tag> const& a, base_uint<Bits, Tag> const& b)
|
||||
{
|
||||
return compare(a, b) == 0;
|
||||
}
|
||||
|
||||
template <std::size_t Bits, class Tag>
|
||||
inline bool
|
||||
operator!=(base_uint<Bits, Tag> const& a, base_uint<Bits, Tag> const& b)
|
||||
{
|
||||
return compare(a, b) != 0;
|
||||
return (lhs <=> rhs) == 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
template <std::size_t Bits, class Tag>
|
||||
inline bool
|
||||
inline constexpr bool
|
||||
operator==(base_uint<Bits, Tag> const& a, std::uint64_t b)
|
||||
{
|
||||
return a == base_uint<Bits, Tag>(b);
|
||||
}
|
||||
|
||||
template <std::size_t Bits, class Tag>
|
||||
inline bool
|
||||
operator!=(base_uint<Bits, Tag> const& a, std::uint64_t b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
template <std::size_t Bits, class Tag>
|
||||
inline const base_uint<Bits, Tag>
|
||||
inline constexpr base_uint<Bits, Tag>
|
||||
operator^(base_uint<Bits, Tag> const& a, base_uint<Bits, Tag> const& b)
|
||||
{
|
||||
return base_uint<Bits, Tag>(a) ^= b;
|
||||
}
|
||||
|
||||
template <std::size_t Bits, class Tag>
|
||||
inline const base_uint<Bits, Tag>
|
||||
inline constexpr base_uint<Bits, Tag>
|
||||
operator&(base_uint<Bits, Tag> const& a, base_uint<Bits, Tag> const& b)
|
||||
{
|
||||
return base_uint<Bits, Tag>(a) &= b;
|
||||
}
|
||||
|
||||
template <std::size_t Bits, class Tag>
|
||||
inline const base_uint<Bits, Tag>
|
||||
inline constexpr base_uint<Bits, Tag>
|
||||
operator|(base_uint<Bits, Tag> const& a, base_uint<Bits, Tag> const& b)
|
||||
{
|
||||
return base_uint<Bits, Tag>(a) |= b;
|
||||
}
|
||||
|
||||
template <std::size_t Bits, class Tag>
|
||||
inline const base_uint<Bits, Tag>
|
||||
inline constexpr base_uint<Bits, Tag>
|
||||
operator+(base_uint<Bits, Tag> const& a, base_uint<Bits, Tag> const& b)
|
||||
{
|
||||
return base_uint<Bits, Tag>(a) += b;
|
||||
|
||||
Reference in New Issue
Block a user