Repository: bitcoin/bitcoin
File: src/arith_uint256.h (C/C++)

Code before:
        --(*this);
        return ret;
    }

    /** Numeric ordering (unlike \ref base_blob::Compare) */
    int CompareTo(const base_uint& b) const;
    bool EqualTo(uint64_t b) const;

    friend inline base_uint operator+(const base_uint& a, const base_uint& b) { return base_uint(a) += b; }
    friend inline base_uint operator-(const base_uint& a, const base_uint& b) { return base_uint(a) -= b; }
    friend inline base_uint operator*(const base_uint& a, const base_uint& b) { return base_uint(a) *= b; }
    friend inline base_uint operator/(const base_uint& a, const base_uint& b) { return base_uint(a) /= b; }
    friend inline base_uint operator|(const base_uint& a, const base_uint& b) { return base_uint(a) |= b; }
    friend inline base_uint operator&(const base_uint& a, const base_uint& b) { return base_uint(a) &= b; }
    friend inline base_uint operator^(const base_uint& a, const base_uint& b) { return base_uint(a) ^= b; }
    friend inline base_uint operator>>(const base_uint& a, int shift) { return base_uint(a) >>= shift; }
    friend inline base_uint operator<<(const base_uint& a, int shift) { return base_uint(a) <<= shift; }
    friend inline base_uint operator*(const base_uint& a, uint32_t b) { return base_uint(a) *= b; }
    friend inline bool operator==(const base_uint& a, const base_uint& b) { return memcmp(a.pn, b.pn, sizeof(a.pn)) == 0; }
    friend inline bool operator!=(const base_uint& a, const base_uint& b) { return memcmp(a.pn, b.pn, sizeof(a.pn)) != 0; }
    friend inline bool operator>(const base_uint& a, const base_uint& b) { return a.CompareTo(b) > 0; }
    friend inline bool operator<(const base_uint& a, const base_uint& b) { return a.CompareTo(b) < 0; }
    friend inline bool operator>=(const base_uint& a, const base_uint& b) { return a.CompareTo(b) >= 0; }
    friend inline bool operator<=(const base_uint& a, const base_uint& b) { return a.CompareTo(b) <= 0; }
    friend inline bool operator==(const base_uint& a, uint64_t b) { return a.EqualTo(b); }
    friend inline bool operator!=(const base_uint& a, uint64_t b) { return !a.EqualTo(b); }

    /** Hex encoding of the number (with the most significant digits first). */
    std::string GetHex() const;
    std::string ToString() const;

    unsigned int size() const
    {
        return sizeof(pn);
    }

    /**
     * Returns the position of the highest bit set plus one, or zero if the
     * value is zero.
     */
    unsigned int bits() const;

    uint64_t GetLow64() const
    {
        static_assert(WIDTH >= 2, "Assertion WIDTH >= 2 failed (WIDTH = BITS / 32). BITS is a template parameter.");
        return pn[0] | (uint64_t)pn[1] << 32;
    }
};

/** 256-bit unsigned big integer. */
class arith_uint256 : public base_uint<256> {

Review comment (refactor):
Can you explain why you remove this line of code? IIUC, this means that `!=` with `uint64_t` will now go through the implicit constructor call, and then through the new `operator<=>`.

If it is intentional, then removing operator `==` with `uint64_t` should be done as well for the same reason? If not, it may be better to keep them?

Mostly a consistency style-question, feel free to ignore.

Code after:
        const base_uint ret = *this;
        --(*this);
        return ret;
    }

    /** Numeric ordering (unlike \ref base_blob::Compare) */
    int CompareTo(const base_uint& b) const;
    bool EqualTo(uint64_t b) const;

    friend inline base_uint operator+(const base_uint& a, const base_uint& b) { return base_uint(a) += b; }
    friend inline base_uint operator-(const base_uint& a, const base_uint& b) { return base_uint(a) -= b; }
    friend inline base_uint operator*(const base_uint& a, const base_uint& b) { return base_uint(a) *= b; }
    friend inline base_uint operator/(const base_uint& a, const base_uint& b) { return base_uint(a) /= b; }
    friend inline base_uint operator|(const base_uint& a, const base_uint& b) { return base_uint(a) |= b; }
    friend inline base_uint operator&(const base_uint& a, const base_uint& b) { return base_uint(a) &= b; }
    friend inline base_uint operator^(const base_uint& a, const base_uint& b) { return base_uint(a) ^= b; }
    friend inline base_uint operator>>(const base_uint& a, int shift) { return base_uint(a) >>= shift; }
    friend inline base_uint operator<<(const base_uint& a, int shift) { return base_uint(a) <<= shift; }
    friend inline base_uint operator*(const base_uint& a, uint32_t b) { return base_uint(a) *= b; }
    friend inline bool operator==(const base_uint& a, const base_uint& b) { return memcmp(a.pn, b.pn, sizeof(a.pn)) == 0; }
    friend inline std::strong_ordering operator<=>(const base_uint& a, const base_uint& b) { return a.CompareTo(b) <=> 0; }
    friend inline bool operator==(const base_uint& a, uint64_t b) { return a.EqualTo(b); }

    /** Hex encoding of the number (with the most significant digits first). */
    std::string GetHex() const;
    std::string ToString() const;

    unsigned int size() const
    {
        return sizeof(pn);
    }

    /**
     * Returns the position of the highest bit set plus one, or zero if the
     * value is zero.
     */
    unsigned int bits() const;

    uint64_t GetLow64() const
    {
        static_assert(WIDTH >= 2, "Assertion WIDTH >= 2 failed (WIDTH = BITS / 32). BITS is a template parameter.");
        return pn[0] | (uint64_t)pn[1] << 32;
    }
};

/** 256-bit unsigned big integer. */
class arith_uint256 : public base_uint<256> {
public:
    arith_uint256() = default;
    arith_uint256(const base_uint<256>& b) : base_uint<256>(b) {}
    arith_uint256(uint64_t b) : base_uint<256>(b) {}