refactor: C++20 operators #33771

pull purpleKarrot wants to merge 2 commits into bitcoin:master from purpleKarrot:cxx20-operators changing 14 files +7 −106
  1. purpleKarrot commented at 1:49 PM on November 3, 2025: contributor

    Remove all operator!= definitions and provide operator<=> as a replacement where all relational comparison operators were defined before.

    The compiler is able to deduce missing comparison operators from operator!= and operator<=>. The compiler provided operators have the following advantages:

    1. less code
    2. guaranteed consistency

    Refactoring that changes the implementation, or replaces it with = default is left for a separate PR.

  2. refactor: Remove all `operator!=` definitions
    The compiler can deduce `operator!=` from `operator==`.
    5a0f49bd26
  3. refactor: Prefer `<=>` over multiple relational operators
    Define `operator<=>` in classes that have all of `<`, `<=`, `>`, `>=`.
    48840bfc2d
  4. DrahtBot added the label Refactoring on Nov 3, 2025
  5. DrahtBot commented at 1:49 PM on November 3, 2025: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    <!--006a51241073e994b41acfe9ec718e94-->

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/33771.

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    ACK stickies-v, optout21, janb84, Chand-ra, maflcko, sipa

    If your review is incorrectly listed, please copy-paste <code>&lt;!--meta-tag:bot-skip--&gt;</code> into the comment that the bot should ignore.

    <!--174a7506f384e20aa4161008e828411d-->

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #33772 (prevector: simplify implementation of comparison operators and match behavior of std::vector by purpleKarrot)
    • #33711 (transaction: Adding script witness to ToString for CTxIn by Ataraxia009)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->

  6. in src/script/script.h:273 in 48840bfc2d
     269 | @@ -270,18 +270,10 @@ class CScriptNum
     270 |      }
     271 |  
     272 |      inline bool operator==(const int64_t& rhs) const    { return m_value == rhs; }
     273 | -    inline bool operator!=(const int64_t& rhs) const    { return m_value != rhs; }
     274 | -    inline bool operator<=(const int64_t& rhs) const    { return m_value <= rhs; }
     275 | -    inline bool operator< (const int64_t& rhs) const    { return m_value <  rhs; }
     276 | -    inline bool operator>=(const int64_t& rhs) const    { return m_value >= rhs; }
     277 | -    inline bool operator> (const int64_t& rhs) const    { return m_value >  rhs; }
     278 | +    inline auto operator<=>(const int64_t& rhs) const    { return m_value <=> rhs; }
    


    stickies-v commented at 4:19 PM on November 3, 2025:

    nit (here and for all other new operator<=>): perhaps better to be explicit about the std::strong_ordering return type? And perhaps making it constexpr while touching?

    <details> <summary>git diff on 48840bfc2d</summary>

    diff --git a/src/prevector.h b/src/prevector.h
    index d4d90c7350..595be4a603 100644
    --- a/src/prevector.h
    +++ b/src/prevector.h
    @@ -7,6 +7,7 @@
     
     #include <algorithm>
     #include <cassert>
    +#include <compare>
     #include <cstddef>
     #include <cstdint>
     #include <cstdlib>
    @@ -71,8 +72,8 @@ public:
             iterator& operator+=(size_type n) { ptr += n; return *this; }
             iterator operator-(size_type n) const { return iterator(ptr - n); }
             iterator& operator-=(size_type n) { ptr -= n; return *this; }
    -        bool operator==(iterator x) const { return ptr == x.ptr; }
    -        auto operator<=>(iterator x) const { return ptr <=> x.ptr; }
    +        constexpr bool operator==(iterator x) const { return ptr == x.ptr; }
    +        constexpr std::strong_ordering operator<=>(iterator x) const { return ptr <=> x.ptr; }
         };
     
         class const_iterator {
    @@ -99,8 +100,8 @@ public:
             const_iterator& operator+=(size_type n) { ptr += n; return *this; }
             const_iterator operator-(size_type n) const { return const_iterator(ptr - n); }
             const_iterator& operator-=(size_type n) { ptr -= n; return *this; }
    -        bool operator==(const_iterator x) const { return ptr == x.ptr; }
    -        auto operator<=>(const_iterator x) const { return ptr <=> x.ptr; }
    +        constexpr bool operator==(const_iterator x) const { return ptr == x.ptr; }
    +        constexpr std::strong_ordering operator<=>(const_iterator x) const { return ptr <=> x.ptr; }
         };
     
     private:
    diff --git a/src/script/script.h b/src/script/script.h
    index b06be9c975..f1472a7dd3 100644
    --- a/src/script/script.h
    +++ b/src/script/script.h
    @@ -14,6 +14,7 @@
     #include <util/hash_type.h>
     
     #include <cassert>
    +#include <compare>
     #include <cstdint>
     #include <cstring>
     #include <limits>
    @@ -269,11 +270,11 @@ public:
             m_value = set_vch(vch);
         }
     
    -    inline bool operator==(const int64_t& rhs) const    { return m_value == rhs; }
    -    inline auto operator<=>(const int64_t& rhs) const    { return m_value <=> rhs; }
    +    inline constexpr bool operator==(const int64_t& rhs) const    { return m_value == rhs; }
    +    inline constexpr std::strong_ordering operator<=>(const int64_t& rhs) const    { return m_value <=> rhs; }
     
    -    inline bool operator==(const CScriptNum& rhs) const { return operator==(rhs.m_value); }
    -    inline auto operator<=>(const CScriptNum& rhs) const { return operator<=>(rhs.m_value); }
    +    inline constexpr bool operator==(const CScriptNum& rhs) const { return operator==(rhs.m_value); }
    +    inline constexpr std::strong_ordering operator<=>(const CScriptNum& rhs) const { return operator<=>(rhs.m_value); }
     
         inline CScriptNum operator+(   const int64_t& rhs)    const { return CScriptNum(m_value + rhs);}
         inline CScriptNum operator-(   const int64_t& rhs)    const { return CScriptNum(m_value - rhs);}
    diff --git a/src/test/scriptnum10.h b/src/test/scriptnum10.h
    index 402606714d..fd112d6ff7 100644
    --- a/src/test/scriptnum10.h
    +++ b/src/test/scriptnum10.h
    @@ -7,6 +7,7 @@
     #define BITCOIN_TEST_SCRIPTNUM10_H
     
     #include <cassert>
    +#include <compare>
     #include <cstdint>
     #include <limits>
     #include <stdexcept>
    @@ -60,11 +61,11 @@ public:
             m_value = set_vch(vch);
         }
     
    -    inline bool operator==(const int64_t& rhs) const    { return m_value == rhs; }
    -    inline auto operator<=>(const int64_t& rhs) const    { return m_value <=> rhs; }
    +    inline constexpr bool operator==(const int64_t& rhs) const    { return m_value == rhs; }
    +    inline constexpr std::strong_ordering operator<=>(const int64_t& rhs) const    { return m_value <=> rhs; }
     
    -    inline bool operator==(const CScriptNum10& rhs) const { return operator==(rhs.m_value); }
    -    inline auto operator<=>(const CScriptNum10& rhs) const { return operator<=>(rhs.m_value); }
    +    inline constexpr bool operator==(const CScriptNum10& rhs) const { return operator==(rhs.m_value); }
    +    inline constexpr std::strong_ordering operator<=>(const CScriptNum10& rhs) const { return operator<=>(rhs.m_value); }
     
         inline CScriptNum10 operator+(   const int64_t& rhs)    const { return CScriptNum10(m_value + rhs);}
         inline CScriptNum10 operator-(   const int64_t& rhs)    const { return CScriptNum10(m_value - rhs);}
    diff --git a/src/util/bitdeque.h b/src/util/bitdeque.h
    index 21934e02da..be3e0fd859 100644
    --- a/src/util/bitdeque.h
    +++ b/src/util/bitdeque.h
    @@ -6,6 +6,7 @@
     #define BITCOIN_UTIL_BITDEQUE_H
     
     #include <bitset>
    +#include <compare>
     #include <cstddef>
     #include <deque>
     #include <limits>
    @@ -99,8 +100,8 @@ class bitdeque
             friend Iterator operator+(Iterator x, difference_type dist) { x += dist; return x; }
             friend Iterator operator+(difference_type dist, Iterator x) { x += dist; return x; }
             friend Iterator operator-(Iterator x, difference_type dist) { x -= dist; return x; }
    -        friend auto operator<=>(const Iterator& x, const Iterator& y) { return std::tie(x.m_it, x.m_bitpos) <=> std::tie(y.m_it, y.m_bitpos); }
    -        friend bool operator==(const Iterator& x, const Iterator& y) { return x.m_it == y.m_it && x.m_bitpos == y.m_bitpos; }
    +        friend constexpr std::strong_ordering operator<=>(const Iterator& x, const Iterator& y) { return std::tie(x.m_it, x.m_bitpos) <=> std::tie(y.m_it, y.m_bitpos); }
    +        friend constexpr bool operator==(const Iterator& x, const Iterator& y) { return x.m_it == y.m_it && x.m_bitpos == y.m_bitpos; }
             reference operator*() const { return (*m_it)[m_bitpos]; }
             reference operator[](difference_type pos) const { return *(*this + pos); }
         };
    
    

    </details>


    purpleKarrot commented at 5:23 PM on November 3, 2025:

    Thanks @stickies-v.

    I am not convinced about std::strong_ordering. constexpr will definitely be added as a follow up, together with = default where appropriate.

  7. stickies-v approved
  8. stickies-v commented at 4:19 PM on November 3, 2025: contributor

    utACK 48840bfc2d7beeac0ddf56a3c26b243156ec8936. Pretty straightforward cleanup taking advantage of C++20 improvements, nice.

  9. optout21 commented at 2:37 PM on November 11, 2025: none

    utACK 48840bfc2d7beeac0ddf56a3c26b243156ec8936

    Straightforward refactoring resulting in code removal 😎 First commit removes != operator where == exits. Second commit replaces 4 comparison operators with the new <=> spaceship operator. My only concern is that competence with the new <=> operator may not be extensive across the developer community of this project, but hey, it's time to learn!

  10. optout21 commented at 2:38 PM on November 11, 2025: none

    I wonder whether it would it be possible check for superfluous comparison operator implementations in linting?

  11. janb84 commented at 3:40 PM on December 1, 2025: contributor

    ACK 48840bfc2d7beeac0ddf56a3c26b243156ec8936

    Reducing custom handwritten boilerplate and replacing it with modern idioms is not something we should shun to do (imho). Using the spaceship operation <=> will use the compiler to generate the other operators correctly.

    Was a bit worried that the spaceship did not yet land on apple clang, given the documentation <img width="761" height="383" alt="Screenshot 2025-12-01 at 15 42 16" src="https://github.com/user-attachments/assets/e38a7194-0a00-40e7-9850-f9a1f193d032" />

    But it compiles fine on MacOS 26 :

    
    100% tests passed, 0 tests failed out of 134
    
    Total Test time (real) =  82.35 sec
    
    The following tests did not run:
             89 - script_assets_tests (Skipped)
    arjan@M1-Max bitcoin % utest
    zsh: command not found: utest
    arjan@M1-Max bitcoin % ./build/bin/test_bitcoin
    Running 625 test cases...
    
    *** No errors detected
    

    This line makes me unsure if the support is there for older systems: <img width="757" height="56" alt="Screenshot 2025-12-01 at 15 43 00" src="https://github.com/user-attachments/assets/99570eb5-6d93-45ba-8ace-5ce1b569a57d" />

    Guix (SKD 15) also builds fine:

    Host architecture: aarch64 Commit: 48840bfc2d7b

     7ae74e91099585fab44a8eba15b66a1cd70e9ec615255a8418e12c113cd2b22f guix-build-48840bfc2d7b/output/aarch64-linux-gnu/SHA256SUMS.part 
     328f5720e716f8dc6c07155c3b0e263a0c3bb08083e1afc5b9d7819d88edcae1 guix-build-48840bfc2d7b/output/aarch64-linux-gnu/bitcoin-48840bfc2d7b-aarch64-linux-gnu-debug.tar.gz 
     364f8b5fed3df38c4e5e0f36081ea0ab752e1d842ee6aa8ef79630b644865dfd guix-build-48840bfc2d7b/output/aarch64-linux-gnu/bitcoin-48840bfc2d7b-aarch64-linux-gnu.tar.gz 
     d600f7a4cf2c0f913b493ca26afb6818873cf7cb4c4aaff8be9ba5356ae5aeb0 guix-build-48840bfc2d7b/output/arm-linux-gnueabihf/SHA256SUMS.part 
     18e399e645ee0d130d306e2d28c20ca256ae4c82c0eb097cd5af6d45ed23fad5 guix-build-48840bfc2d7b/output/arm-linux-gnueabihf/bitcoin-48840bfc2d7b-arm-linux-gnueabihf-debug.tar.gz 
     aff5f14e0ff6e8c7086adbb7ccf31515a15040e0d882659d33a4a828ac9cfd77 guix-build-48840bfc2d7b/output/arm-linux-gnueabihf/bitcoin-48840bfc2d7b-arm-linux-gnueabihf.tar.gz 
     1c259381c2db38ea7aa7dd1d0503a73d3af9e3d5c7fb1f0debdda8c3f0378d1c guix-build-48840bfc2d7b/output/arm64-apple-darwin/SHA256SUMS.part 
     ddf9c751d147b766dbc0ee4dff424f812c8c3717998eeab24ec63fc9f85c82c7 guix-build-48840bfc2d7b/output/arm64-apple-darwin/bitcoin-48840bfc2d7b-arm64-apple-darwin-codesigning.tar.gz 
     02f0b34dd9b87400c12a945e337912c806dffb4c4243e6f5dcacd52c3fc6ad7f guix-build-48840bfc2d7b/output/arm64-apple-darwin/bitcoin-48840bfc2d7b-arm64-apple-darwin-unsigned.tar.gz 
     e942a32dc63461b5e99e7745026115e45b03bd8fc76741b8ab20c56e42488820 guix-build-48840bfc2d7b/output/arm64-apple-darwin/bitcoin-48840bfc2d7b-arm64-apple-darwin-unsigned.zip 
     788f9ced2fbac52f2291c360e77067c56aa503a7172b6787309ac0b6d9974efe guix-build-48840bfc2d7b/output/dist-archive/bitcoin-48840bfc2d7b.tar.gz 
     2bf8e1dedd00f91597abc93dd08d067f47dba4e5eebab7f2ac5d11fcbaff4256 guix-build-48840bfc2d7b/output/powerpc64-linux-gnu/SHA256SUMS.part 
     2feefe7552a90c8b2206566e3d0c14896dc1bfa2a80794ae618132edaf5122e9 guix-build-48840bfc2d7b/output/powerpc64-linux-gnu/bitcoin-48840bfc2d7b-powerpc64-linux-gnu-debug.tar.gz 
     4c3bbbe588d28bf03a72f01ec06235e5477d35e8c6522c48fec685d77493a609 guix-build-48840bfc2d7b/output/powerpc64-linux-gnu/bitcoin-48840bfc2d7b-powerpc64-linux-gnu.tar.gz 
     15a1e20e3f6ca4860d2d8828e8764720bb4f163d7f07080d109ff356854c8266 guix-build-48840bfc2d7b/output/riscv64-linux-gnu/SHA256SUMS.part 
     680a35ced59259d97000d941795edda383ce6f535f876008753e0a437a7ba3a1 guix-build-48840bfc2d7b/output/riscv64-linux-gnu/bitcoin-48840bfc2d7b-riscv64-linux-gnu-debug.tar.gz 
     baaca17bb5e75998486dbb89d8e11326f90c71c284e35733247625e4cdef43bf guix-build-48840bfc2d7b/output/riscv64-linux-gnu/bitcoin-48840bfc2d7b-riscv64-linux-gnu.tar.gz 
     012f1b4f8c76758c16f72fdfc47777e3253c5ba0733d6a97190bac760c7753ee guix-build-48840bfc2d7b/output/x86_64-apple-darwin/SHA256SUMS.part 
     16bc8a00df772b3b5a379bdee25f894ca6f2f85944c3def500ab0387ec1581c2 guix-build-48840bfc2d7b/output/x86_64-apple-darwin/bitcoin-48840bfc2d7b-x86_64-apple-darwin-codesigning.tar.gz 
     7f38f933235fe2c97e1267b39769d3932ab230c4f7807b37812f405a3852cca4 guix-build-48840bfc2d7b/output/x86_64-apple-darwin/bitcoin-48840bfc2d7b-x86_64-apple-darwin-unsigned.tar.gz 
     3788cb3a019886c703f8718e7d5f240264f867e5702a28a1743a7f3006919e13 guix-build-48840bfc2d7b/output/x86_64-apple-darwin/bitcoin-48840bfc2d7b-x86_64-apple-darwin-unsigned.zip 
     f2a81cc5dece9e21410f0a19c1aefa2faddfca33093ec98c021dbd4b75fca4c8 guix-build-48840bfc2d7b/output/x86_64-linux-gnu/SHA256SUMS.part 
     102e27dbbde0b7c0708f7acea622bc2251191d26e77338f4fd12a2c4a1f64612 guix-build-48840bfc2d7b/output/x86_64-linux-gnu/bitcoin-48840bfc2d7b-x86_64-linux-gnu-debug.tar.gz 
     a6ceac36f0d0584f68cbb56d4a6f539857a475349c22c623a07e4dd2d59ee356 guix-build-48840bfc2d7b/output/x86_64-linux-gnu/bitcoin-48840bfc2d7b-x86_64-linux-gnu.tar.gz 
     e6507f4368396f2a1437be9ef0a757440524990d2bc98b6e5f7661f3c15597b2 guix-build-48840bfc2d7b/output/x86_64-w64-mingw32/SHA256SUMS.part 
     732a99e42f7a9515f6c796fb4221cc19bcbc26a1db33b2a83fa3c807b3e8cc35 guix-build-48840bfc2d7b/output/x86_64-w64-mingw32/bitcoin-48840bfc2d7b-win64-codesigning.tar.gz 
     828abc438986151f4959996717d469e04ac534f6bf98a0a280e807c61801882c guix-build-48840bfc2d7b/output/x86_64-w64-mingw32/bitcoin-48840bfc2d7b-win64-debug.zip 
     76d57ff1512d9eab0a7804aa227db1d93333f17564e612e276d5c6a0fe89ff51 guix-build-48840bfc2d7b/output/x86_64-w64-mingw32/bitcoin-48840bfc2d7b-win64-setup-unsigned.exe 
     0924cd8c4ba99b2be857d494be2d32ed6bd134cfe99b8b7b9c53a0abfa095956 guix-build-48840bfc2d7b/output/x86_64-w64-mingw32/bitcoin-48840bfc2d7b-win64-unsigned.zip 
    

    benchmarks: this PR: | ns/op | op/s | err% | total | benchmark |--------------------:|--------------------:|--------:|----------:|:---------- | 3.66 | 273,207,365.58 | 0.9% | 0.01 | PrevectorClearNontrivial | 5.47 | 182,981,087.16 | 1.9% | 0.01 | PrevectorClearTrivial | 221.03 | 4,524,203.13 | 1.3% | 0.01 | PrevectorDeserializeNontrivial | 12.88 | 77,654,787.98 | 1.0% | 0.01 | PrevectorDeserializeTrivial | - | - | - | - | :boom: PrevectorDestructorNontrivial (iterations overflow. Maybe your code got optimized away?) | - | - | - | - | :boom: PrevectorDestructorTrivial (iterations overflow. Maybe your code got optimized away?) | 1,148.86 | 870,426.34 | 1.5% | 0.01 | PrevectorFillVectorDirectNontrivial | 297.98 | 3,355,948.40 | 1.2% | 0.01 | PrevectorFillVectorDirectTrivial | 4,150.18 | 240,953.25 | 0.3% | 0.01 | PrevectorFillVectorIndirectNontrivial | 4,003.70 | 249,768.73 | 4.7% | 0.01 | PrevectorFillVectorIndirectTrivial | 1.89 | 528,716,700.36 | 0.6% | 0.01 | PrevectorResizeNontrivial | 2.85 | 350,494,388.31 | 0.4% | 0.01 | PrevectorResizeTrivial

    | ns/job | job/s | err% | total | benchmark |--------------------:|--------------------:|--------:|----------:|:---------- | 225.66 | 4,431,399.41 | 4.6% | 0.09 | CCheckQueueSpeedPrevectorJob

    Master:

    | ns/op | op/s | err% | total | benchmark |--------------------:|--------------------:|--------:|----------:|:---------- | 3.63 | 275,735,101.26 | 0.1% | 0.01 | PrevectorClearNontrivial | 5.32 | 187,794,641.77 | 0.1% | 0.01 | PrevectorClearTrivial | 219.86 | 4,548,382.05 | 0.9% | 0.01 | PrevectorDeserializeNontrivial | 11.71 | 85,371,714.77 | 0.8% | 0.01 | PrevectorDeserializeTrivial | - | - | - | - | :boom: PrevectorDestructorNontrivial (iterations overflow. Maybe your code got optimized away?) | - | - | - | - | :boom: PrevectorDestructorTrivial (iterations overflow. Maybe your code got optimized away?) | 1,372.81 | 728,434.76 | 3.6% | 0.01 | PrevectorFillVectorDirectNontrivial | 315.76 | 3,166,924.15 | 2.1% | 0.01 | PrevectorFillVectorDirectTrivial | 4,324.56 | 231,237.32 | 1.2% | 0.01 | PrevectorFillVectorIndirectNontrivial | 3,856.83 | 259,280.23 | 1.1% | 0.01 | PrevectorFillVectorIndirectTrivial | 1.85 | 539,265,429.27 | 0.3% | 0.01 | PrevectorResizeNontrivial | 2.72 | 367,563,122.86 | 0.6% | 0.01 | PrevectorResizeTrivial

    | ns/job | job/s | err% | total | benchmark |--------------------:|--------------------:|--------:|----------:|:---------- | 258.39 | 3,870,177.88 | 4.8% | 0.10 | CCheckQueueSpeedPrevectorJob

  12. fanquake requested review from maflcko on Dec 5, 2025
  13. Chand-ra commented at 8:37 AM on December 8, 2025: none

    tACK 48840bf. Built the PR and ran unit tests; everything passes.

    Verified that all instances of operator!= have been removed and operator<=> replaces combined implementations of <, <=, >, and >=. (Note: PR #33772 and not this one gets rid of operator< in src/prevector.h.)

  14. maflcko commented at 3:54 PM on December 8, 2025: member

    review ACK 48840bfc2d7beeac0ddf56a3c26b243156ec8936 🌖

    <details><summary>Show signature</summary>

    Signature:

    untrusted comment: signature from minisign secret key on empty file; verify via: minisign -Vm "${path_to_any_empty_file}" -P RWTRmVTMeKV5noAMqVlsMugDDCyyTSbA3Re5AkUrhvLVln0tSaFWglOw -x "${path_to_this_whole_four_line_signature_blob}"
    RUTRmVTMeKV5npGrKx1nqXCw5zeVHdtdYURB/KlyA/LMFgpNCs+SkW9a8N95d+U4AP1RJMi+krxU1A3Yux4bpwZNLvVBKy0wLgM=
    trusted comment: review ACK 48840bfc2d7beeac0ddf56a3c26b243156ec8936 🌖
    RJCzzHS7aZcc9j1dS+BlIns6fkD9vUnjg/5rVEcIpZ07JGtNbdDramcmgcbbznLHZYBJgSUdVocxGNYeupAnCw==
    

    </details>

  15. sipa commented at 4:36 PM on December 8, 2025: member

    ACK 48840bfc2d7beeac0ddf56a3c26b243156ec8936

    ultra-nit: I think the commit message "The compiler can deduce" is misleading. Of course it can, but the point isn't that it can, it's that the language spec says it must.

  16. fanquake merged this on Dec 8, 2025
  17. fanquake closed this on Dec 8, 2025

  18. maflcko commented at 12:37 PM on December 9, 2025: member

    I think there are some missed cases. It could make sense to include them in a follow-up?

    diff --git a/src/kernel/bitcoinkernel_wrapper.h b/src/kernel/bitcoinkernel_wrapper.h
    index 3fb90da7a9..055ea83808 100644
    --- a/src/kernel/bitcoinkernel_wrapper.h
    +++ b/src/kernel/bitcoinkernel_wrapper.h
    @@ -465,14 +465,9 @@ private:
         TxidApi() = default;
     
     public:
    -    bool operator==(const TxidApi& other) const
    +    friend bool operator==(const Derived& lhs, const Derived& rhs)
         {
    -        return btck_txid_equals(impl(), other.impl()) != 0;
    -    }
    -
    -    bool operator!=(const TxidApi& other) const
    -    {
    -        return btck_txid_equals(impl(), other.impl()) == 0;
    +        return btck_txid_equals(lhs.get(), rhs.get()) != 0;
         }
     
         std::array<std::byte, 32> ToBytes() const
    @@ -665,14 +660,9 @@ private:
         }
     
     public:
    -    bool operator==(const Derived& other) const
    -    {
    -        return btck_block_hash_equals(impl(), other.get()) != 0;
    -    }
    -
    -    bool operator!=(const Derived& other) const
    +    friend bool operator==(const Derived& lhs, const Derived& rhs)
         {
    -        return btck_block_hash_equals(impl(), other.get()) == 0;
    +        return btck_block_hash_equals(lhs.get(), rhs.get()) != 0;
         }
     
         std::array<std::byte, 32> ToBytes() const
    

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-04-21 06:12 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me