diff --git a/src/Makefile.am b/src/Makefile.am index 0829eda61e8a..12bc0d23ddac 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -293,6 +293,7 @@ BITCOIN_CORE_H = \ util/bip32.h \ util/bytevectorhash.h \ util/check.h \ + util/enumerate.h \ util/error.h \ util/fees.h \ util/golombrice.h \ diff --git a/src/test/block_reward_reallocation_tests.cpp b/src/test/block_reward_reallocation_tests.cpp index ba9823c1d6d2..2b49f517e6e0 100644 --- a/src/test/block_reward_reallocation_tests.cpp +++ b/src/test/block_reward_reallocation_tests.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include @@ -48,10 +49,9 @@ struct TestChainBRRBeforeActivationSetup : public TestChainSetup static SimpleUTXOMap BuildSimpleUtxoMap(const std::vector& txs) { SimpleUTXOMap utxos; - for (size_t i = 0; i < txs.size(); i++) { - auto& tx = txs[i]; - for (size_t j = 0; j < tx->vout.size(); j++) { - utxos.try_emplace(COutPoint(tx->GetHash(), j), std::make_pair((int)i + 1, tx->vout[j].nValue)); + for (auto [i, tx] : enumerate(txs)) { + for (auto [j, output] : enumerate(tx->vout)) { + utxos.try_emplace(COutPoint(tx->GetHash(), j), std::make_pair((int)i + 1, output.nValue)); } } return utxos; @@ -104,9 +104,9 @@ static void SignTransaction(const CTxMemPool& mempool, CMutableTransaction& tx, FillableSigningProvider tempKeystore; tempKeystore.AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey()); - for (size_t i = 0; i < tx.vin.size(); i++) { + for (auto [i, input] : enumerate(tx.vin)) { uint256 hashBlock; - CTransactionRef txFrom = GetTransaction(/* block_index */ nullptr, &mempool, tx.vin[i].prevout.hash, Params().GetConsensus(), hashBlock); + CTransactionRef txFrom = GetTransaction(/* block_index */ nullptr, &mempool, input.prevout.hash, Params().GetConsensus(), hashBlock); BOOST_ASSERT(txFrom); BOOST_ASSERT(SignSignature(tempKeystore, *txFrom, tx, i, SIGHASH_ALL)); } diff --git a/src/util/enumerate.h b/src/util/enumerate.h new file mode 100644 index 000000000000..8bec72dc58c1 --- /dev/null +++ b/src/util/enumerate.h @@ -0,0 +1,40 @@ +// Copyright (c) 2022 The Dash Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_UTIL_ENUMERATE_H +#define BITCOIN_UTIL_ENUMERATE_H + +#include +#include + +/** + * similar to python's enumerate(iterable). + * @tparam T type of iterable, automatically deduced + * @tparam TIter + * @param iterable an iterable object, can be a temporary + * @return struct containing a size_t index, and it's element in iterable + */ +template ())), + typename = decltype(std::end(std::declval()))> +constexpr auto enumerate(T && iterable) +{ + struct iterator + { + size_t i; + TIter iter; + bool operator != (const iterator & other) const { return iter != other.iter; } + void operator ++ () { ++i; ++iter; } + auto operator * () const { return std::tie(i, *iter); } + }; + struct iterable_wrapper + { + T iterable; + auto begin() { return iterator{ 0, std::begin(iterable) }; } + auto end() { return iterator{ 0, std::end(iterable) }; } + }; + return iterable_wrapper{ std::forward(iterable) }; +} + +#endif // BITCOIN_UTIL_ENUMERATE_H