nit: for non-trivial functions, I think it helps to narrow down T
instead of having to deduct it from its callsites and usage.
What do you think about adding an IsCoinRef
concept, and adding std::span
to the function signature?
0diff --git a/src/consensus/tx_verify.cpp b/src/consensus/tx_verify.cpp
1index 97f8241089..ab27387cc4 100644
2--- a/src/consensus/tx_verify.cpp
3+++ b/src/consensus/tx_verify.cpp
4@@ -14,6 +14,8 @@
5 #include <util/check.h>
6 #include <util/moneystr.h>
7
8+#include <span>
9+
10 template <typename T>
11 static constexpr const Coin& GetCoin(const T& item)
12 {
13@@ -158,8 +160,8 @@ template unsigned int GetP2SHSigOpCount<std::span<const Coin>>(
14 template unsigned int GetP2SHSigOpCount<std::span<std::reference_wrapper<const Coin>>>(
15 const CTransaction& tx, const std::span<std::reference_wrapper<const Coin>>);
16
17-template <typename T>
18-int64_t GetTransactionSigOpCost(const CTransaction& tx, const T coins, uint32_t flags)
19+template<IsCoinRef CoinRef>
20+int64_t GetTransactionSigOpCost(const CTransaction& tx, std::span<CoinRef> coins, uint32_t flags)
21 {
22 int64_t nSigOps = GetLegacySigOpCount(tx) * WITNESS_SCALE_FACTOR;
23
24@@ -172,18 +174,18 @@ int64_t GetTransactionSigOpCost(const CTransaction& tx, const T coins, uint32_t
25
26 Assert(coins.size() == tx.vin.size());
27 auto input_it = tx.vin.begin();
28- for (auto it = coins.begin(); it != coins.end(); ++it, ++input_it) {
29- const Coin& coin{GetCoin(*it)};
30+ for (const Coin& coin : coins) {
31 assert(!coin.IsSpent());
32 const CTxOut &prevout = coin.out;
33 nSigOps += CountWitnessSigOps(input_it->scriptSig, prevout.scriptPubKey, &input_it->scriptWitness, flags);
34+ ++input_it;
35 }
36 return nSigOps;
37 }
38-template int64_t GetTransactionSigOpCost<std::span<const Coin>>(
39+template int64_t GetTransactionSigOpCost<const Coin>(
40 const CTransaction& tx, std::span<const Coin> coins, uint32_t flags);
41
42-template int64_t GetTransactionSigOpCost<std::span<std::reference_wrapper<const Coin>>>(
43+template int64_t GetTransactionSigOpCost<std::reference_wrapper<const Coin>>(
44 const CTransaction& tx, const std::span<std::reference_wrapper<const Coin>> coins, uint32_t flags);
45
46 template <typename T>
47diff --git a/src/consensus/tx_verify.h b/src/consensus/tx_verify.h
48index 88b2d6164b..b8ab114306 100644
49--- a/src/consensus/tx_verify.h
50+++ b/src/consensus/tx_verify.h
51@@ -48,6 +48,8 @@ unsigned int GetLegacySigOpCount(const CTransaction& tx);
52 template <typename T>
53 unsigned int GetP2SHSigOpCount(const CTransaction& tx, const T coins);
54
55+template<typename T>
56+concept IsCoinRef = std::convertible_to<T, const Coin&>;
57 /**
58 * Compute total signature operation cost of a transaction.
59 * [@param](/bitcoin-bitcoin/contributor/param/)[in] tx Transaction for which we are computing the cost
60@@ -55,8 +57,8 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const T coins);
61 * [@param](/bitcoin-bitcoin/contributor/param/)[in] flags Script verification flags
62 * [@return](/bitcoin-bitcoin/contributor/return/) Total signature operation cost of tx
63 */
64-template <typename T>
65-int64_t GetTransactionSigOpCost(const CTransaction& tx, const T coins, uint32_t flags);
66+template<IsCoinRef CoinRef>
67+int64_t GetTransactionSigOpCost(const CTransaction& tx, std::span<CoinRef> coins, uint32_t flags);
68
69 /**
70 * Check if transaction is final and can be included in a block with the
(the same applies for GetLegacySigOpCount
and GetP2SHSigOpCount
)
edit: I see this is already (partially) suggested and addressed in #32317 (review), I think adding the IsCoinRef
concept could still be nice but less important than specifying the std::span