-
Notifications
You must be signed in to change notification settings - Fork 37.8k
Replace MakeSpan helper with Span deduction guide #23413
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsReviewers, this pull request conflicts with the following ones:
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Concept ACK on moving Span closer to std::span. Though I am wondering some deductions are omitted.
See patch:
diff --git a/src/net.cpp b/src/net.cpp
index ad558dd598..b323d17134 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -738,7 +738,7 @@ std::optional<CNetMessage> V1TransportDeserializer::GetMessage(const std::chrono
if (memcmp(hash.begin(), hdr.pchChecksum, CMessageHeader::CHECKSUM_SIZE) != 0) {
LogPrint(BCLog::NET, "Header error: Wrong checksum (%s, %u bytes), expected %s was %s, peer=%d\n",
SanitizeString(msg->m_command), msg->m_message_size,
- HexStr(Span<uint8_t>(hash.begin(), hash.begin() + CMessageHeader::CHECKSUM_SIZE)),
+ HexStr(Span{hash.begin(), hash.begin() + CMessageHeader::CHECKSUM_SIZE}),
HexStr(hdr.pchChecksum),
m_node_id);
out_err_raw_size = msg->m_raw_message_size;
@@ -1556,7 +1556,7 @@ void CConnman::SocketHandler()
if (nBytes > 0)
{
bool notify = false;
- if (!pnode->ReceiveMsgBytes(Span<const uint8_t>(pchBuf, nBytes), notify))
+ if (!pnode->ReceiveMsgBytes(Span(pchBuf, nBytes), notify))
pnode->CloseSocketDisconnect();
RecordBytesRecv(nBytes);
if (notify) {
diff --git a/src/netaddress.cpp b/src/netaddress.cpp
index 97ad40aa6e..201b797a0d 100644
--- a/src/netaddress.cpp
+++ b/src/netaddress.cpp
@@ -303,7 +303,7 @@ CNetAddr::CNetAddr(const struct in_addr& ipv4Addr)
CNetAddr::CNetAddr(const struct in6_addr& ipv6Addr, const uint32_t scope)
{
- SetLegacyIPv6(Span<const uint8_t>(reinterpret_cast<const uint8_t*>(&ipv6Addr), sizeof(ipv6Addr)));
+ SetLegacyIPv6(Span{reinterpret_cast<const uint8_t*>(&ipv6Addr), sizeof(ipv6Addr)});
m_scope_id = scope;
}
diff --git a/src/pubkey.h b/src/pubkey.h
index e4e3a9560b..dcbdca8ebd 100644
--- a/src/pubkey.h
+++ b/src/pubkey.h
@@ -242,7 +242,7 @@ public:
explicit XOnlyPubKey(Span<const unsigned char> bytes);
/** Construct an x-only pubkey from a normal pubkey. */
- explicit XOnlyPubKey(const CPubKey& pubkey) : XOnlyPubKey(Span<const unsigned char>(pubkey.begin() + 1, pubkey.begin() + 33)) {}
+ explicit XOnlyPubKey(const CPubKey& pubkey) : XOnlyPubKey(Span{pubkey.begin() + 1, pubkey.begin() + 33}) {}
/** Verify a Schnorr signature against this public key.
*
diff --git a/src/rpc/util.cpp b/src/rpc/util.cpp
index 2d7f5f2894..c72f08a5ff 100644
--- a/src/rpc/util.cpp
+++ b/src/rpc/util.cpp
@@ -317,7 +317,7 @@ public:
UniValue obj(UniValue::VOBJ);
obj.pushKV("iswitness", true);
obj.pushKV("witness_version", (int)id.version);
- obj.pushKV("witness_program", HexStr(Span<const unsigned char>(id.program, id.length)));
+ obj.pushKV("witness_program", HexStr(Span{id.program, id.length}));
return obj;
}
};
diff --git a/src/script/descriptor.cpp b/src/script/descriptor.cpp
index 95611fc909..b023d199d5 100644
--- a/src/script/descriptor.cpp
+++ b/src/script/descriptor.cpp
@@ -1251,7 +1251,7 @@ std::unique_ptr<PubkeyProvider> InferXOnlyPubkey(const XOnlyPubKey& xkey, ParseS
std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptContext ctx, const SigningProvider& provider)
{
if (ctx == ParseScriptContext::P2TR && script.size() == 34 && script[0] == 32 && script[33] == OP_CHECKSIG) {
- XOnlyPubKey key{Span<const unsigned char>{script.data() + 1, script.data() + 33}};
+ XOnlyPubKey key{Span{script.data() + 1, script.data() + 33}};
return std::make_unique<PKDescriptor>(InferXOnlyPubkey(key, ctx, provider));
}
diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp
index eafa9840d7..2d84a28981 100644
--- a/src/script/interpreter.cpp
+++ b/src/script/interpreter.cpp
@@ -1858,7 +1858,7 @@ uint256 ComputeTaprootMerkleRoot(Span<const unsigned char> control, const uint25
uint256 k = tapleaf_hash;
for (int i = 0; i < path_len; ++i) {
CHashWriter ss_branch{HASHER_TAPBRANCH};
- Span<const unsigned char> node(control.data() + TAPROOT_CONTROL_BASE_SIZE + TAPROOT_CONTROL_NODE_SIZE * i, TAPROOT_CONTROL_NODE_SIZE);
+ Span node{control.data() + TAPROOT_CONTROL_BASE_SIZE + TAPROOT_CONTROL_NODE_SIZE * i, TAPROOT_CONTROL_NODE_SIZE};
if (std::lexicographical_compare(k.begin(), k.end(), node.begin(), node.end())) {
ss_branch << k << node;
} else {
@@ -1874,7 +1874,7 @@ static bool VerifyTaprootCommitment(const std::vector<unsigned char>& control, c
assert(control.size() >= TAPROOT_CONTROL_BASE_SIZE);
assert(program.size() >= uint256::size());
//! The internal pubkey (x-only, so no Y coordinate parity).
- const XOnlyPubKey p{Span<const unsigned char>{control.data() + 1, control.data() + TAPROOT_CONTROL_BASE_SIZE}};
+ const XOnlyPubKey p{Span{control.data() + 1, control.data() + TAPROOT_CONTROL_BASE_SIZE}};
//! The output pubkey (taken from the scriptPubKey).
const XOnlyPubKey q{program};
// Compute the Merkle root from the leaf and the provided path.
diff --git a/src/signet.cpp b/src/signet.cpp
index aafd1999ee..68fbbc9388 100644
--- a/src/signet.cpp
+++ b/src/signet.cpp
@@ -38,7 +38,7 @@ static bool FetchAndClearCommitmentSection(const Span<const uint8_t> header, CSc
std::vector<uint8_t> pushdata;
while (witness_commitment.GetOp(pc, opcode, pushdata)) {
if (pushdata.size() > 0) {
- if (!found_header && pushdata.size() > (size_t) header.size() && Span<const uint8_t>(pushdata.data(), header.size()) == header) {
+ if (!found_header && pushdata.size() > (size_t)header.size() && Span{pushdata.data(), header.size()} == header) {
// pushdata only counts if it has the header _and_ some data
result.insert(result.end(), pushdata.begin() + header.size(), pushdata.end());
pushdata.erase(pushdata.begin() + header.size(), pushdata.end());
diff --git a/src/span.h b/src/span.h
index 71de70b64f..b04fdd45d1 100644
--- a/src/span.h
+++ b/src/span.h
@@ -218,16 +218,14 @@ public:
};
// Deduction guides for Span
-// For the pointer/size based constructor:
-template <typename T> Span(T*, size_t) -> Span<T>;
+// For the pointer/size based and iterator based constructor:
+template <typename T, typename EndOrSize> Span(T*, EndOrSize) -> Span<T>;
// For the array constructor:
template <typename T, std::size_t N> Span(T (&)[N]) -> Span<T>;
// For the temporaries/rvalue references constructor, only supporting const output.
template <typename T> Span(T&&) -> Span<std::enable_if_t<!std::is_lvalue_reference_v<T>, const std::remove_pointer_t<decltype(std::declval<T&&>().data())>>>;
// For (lvalue) references, supporting mutable output.
template <typename T> Span(T&) -> Span<std::remove_pointer_t<decltype(std::declval<T&>().data())>>;
-// For the copy constructor
-template <typename T> Span(const Span<T>&) -> Span<T>;
/** Pop the last element off a span, and return a reference to that element. */
template <typename T>
diff --git a/src/test/fuzz/asmap.cpp b/src/test/fuzz/asmap.cpp
index d402f8632c..dc37d068d9 100644
--- a/src/test/fuzz/asmap.cpp
+++ b/src/test/fuzz/asmap.cpp
@@ -49,7 +49,7 @@ FUZZ_TARGET(asmap)
CNetAddr net_addr;
if (ipv6) {
assert(addr_size == ADDR_IPV6_SIZE);
- net_addr.SetLegacyIPv6(Span<const uint8_t>(addr_data, addr_size));
+ net_addr.SetLegacyIPv6(Span{addr_data, addr_size});
} else {
assert(addr_size == ADDR_IPV4_SIZE);
in_addr ipv4;
diff --git a/src/test/fuzz/utxo_snapshot.cpp b/src/test/fuzz/utxo_snapshot.cpp
index 8d2a06f11a..d625403fa0 100644
--- a/src/test/fuzz/utxo_snapshot.cpp
+++ b/src/test/fuzz/utxo_snapshot.cpp
@@ -38,7 +38,7 @@ FUZZ_TARGET_INIT(utxo_snapshot, initialize_chain)
{
CAutoFile outfile{fsbridge::fopen(snapshot_path, "wb"), SER_DISK, CLIENT_VERSION};
const auto file_data{ConsumeRandomLengthByteVector(fuzzed_data_provider)};
- outfile << Span<const uint8_t>{file_data};
+ outfile << Span{file_data};
}
const auto ActivateFuzzedSnapshot{[&] {
diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp
index b1300d06ba..a97dc83a3e 100644
--- a/src/test/util_tests.cpp
+++ b/src/test/util_tests.cpp
@@ -142,13 +142,13 @@ BOOST_AUTO_TEST_CASE(util_HexStr)
"04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f");
BOOST_CHECK_EQUAL(
- HexStr(Span<const unsigned char>(
- ParseHex_expected + sizeof(ParseHex_expected),
- ParseHex_expected + sizeof(ParseHex_expected))),
+ HexStr(Span{
+ ParseHex_expected + sizeof(ParseHex_expected),
+ ParseHex_expected + sizeof(ParseHex_expected)}),
"");
BOOST_CHECK_EQUAL(
- HexStr(Span<const unsigned char>(ParseHex_expected, ParseHex_expected)),
+ HexStr(Span{ParseHex_expected, ParseHex_expected}),
"");
std::vector<unsigned char> ParseHex_vec(ParseHex_expected, ParseHex_expected + 5);
diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp
index 1f13b80f3e..48ed50b9a8 100644
--- a/src/wallet/rpcdump.cpp
+++ b/src/wallet/rpcdump.cpp
@@ -35,7 +35,7 @@ std::string static EncodeDumpString(const std::string &str) {
std::stringstream ret;
for (const unsigned char c : str) {
if (c <= 32 || c >= 128 || c == '%') {
- ret << '%' << HexStr(Span<const unsigned char>(&c, 1));
+ ret << '%' << HexStr(Span{&c, 1});
} else {
ret << c;
}
94176a0
to
a9526cf
Compare
Thanks, @MarcoFalke! I've incorporated your suggested changes, plus a few additional simplifications in a second commit. |
360fa9c
to
3576b93
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
review ACK 3576b93 🚛
Show signature and timestamp
Signature:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
review ACK 3576b9393c678352b2ed8a446a62d9639b0a451c 🚛
-----BEGIN PGP SIGNATURE-----
iQGzBAEBCgAdFiEE+rVPoUahrI9sLGYTzit1aX5ppUgFAlwqrYAACgkQzit1aX5p
pUhMqAv/ZMtShuhel+aDB8nQ6xqbVI2SXNOyeXScpWHbu46r1c5dWTlVYgXtHrWM
EXuNFkzMJioCbuWkWbauvox8ccZopPkRBdKseU9jUi/jz+5zp4pK5g0X8WhU1v12
tYL5sQSGCTbl8yKY/L+mSNnoAe0rVAD7nuEAmCLeGU6c8Uv8nz0aj/w6AtDusAD0
K7mJIJpks61r0svCodkCIwWSP+0EmUWOhoEdWdkPywV6F0QeJ2vgVL2Dj507xgMG
BEcCbNX2IdPrYYkybTHKJBlgOaG7+QSMm2rq2MKukSq7Q+ctss0mlA/KT446tTp8
L+5MkXZZDm6m4Kj63ceWU9VF8pVwWNF5F/yvzZobF8lB4wAJo8UORFEAzt8zr9n1
FesE9xru65XvEFyFi0YFYz46D5zX33nbPfe+JRJ1RKRkRXCEJ6XDud7PLhJjjFtc
Y+d8+mCe0A/Fs15kVbv5bZCy4pA1OO6hjYMHsjAzAqWVc4073GCmVIJpYgelcQfU
932Fjcwc
=KdJ0
-----END PGP SIGNATURE-----
I haven't tried, but to the second commit you might be able to add (after a rebase): diff --git a/src/test/key_io_tests.cpp b/src/test/key_io_tests.cpp
index 0361618c82..02268dbcf5 100644
--- a/src/test/key_io_tests.cpp
+++ b/src/test/key_io_tests.cpp
@@ -46,7 +46,7 @@ BOOST_AUTO_TEST_CASE(key_io_valid_parse)
privkey = DecodeSecret(exp_base58string);
BOOST_CHECK_MESSAGE(privkey.IsValid(), "!IsValid:" + strTest);
BOOST_CHECK_MESSAGE(privkey.IsCompressed() == isCompressed, "compressed mismatch:" + strTest);
- BOOST_CHECK_MESSAGE(Span<const uint8_t>{privkey} == Span<const uint8_t>{exp_payload}, "key mismatch:" + strTest);
+ BOOST_CHECK_MESSAGE(Span{privkey} == Span{exp_payload}, "key mismatch:" + strTest);
// Private key must be invalid public key
destination = DecodeDestination(exp_base58string); |
3576b93
to
9883a03
Compare
@MarcoFalke Done (it necessitated adding EDIT: nvm, the |
9883a03
to
f90d5ae
Compare
Rebased and addressed some comments. |
re-ACK f90d5ae 👤 Changes:
Show signature and timestampSignature:
|
To check:
|
Rebased. |
f90d5ae
to
e4aec1e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
re-ACK e4aec1e 🕙
Show signature
Signature:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
re-ACK e4aec1e0cbdc237a26713a34f465e2b485f892f6 🕙
-----BEGIN PGP SIGNATURE-----
iQGzBAEBCgAdFiEE+rVPoUahrI9sLGYTzit1aX5ppUgFAlwqrYAACgkQzit1aX5p
pUgCHAwAic9QG7p6GHs7HQoWstGWqMYJcHHK9R3unb65d8NqlQIGUF+5X4N/V0o/
LTAbZf+Ug+kiUwREEyldTOeJo9WGr1lRQFs5EyHTuB1QGZ0E2p8+0RNc31KUj3Ev
x5sCgGGsDVJrtEt4wbHclqsRebdmIl+AZVLqt3J/dP7sktKwoUU260TCjXrwQnpz
q1S3d6ySfmMdhTU3pWCilGLO6EYZUwJdM2WQD8Ss75CnvkTRadOu1FJTKXbnPySL
krttLbYmCFVqpm9R/MUZRrUKNZ5uPzBfpCRHv/b7XeL6CNJTXYAHZWI93Zlcr4dl
4CAPi5Xbd0tFF0CdLACxXwHQCF6DUEWFFWGhzX+oxKO5/yVOTbWQJBJLuwaLIR9C
rT1GALRBw7LxPCPAZGYI8h6tC76k3BcSpurLjpOHqEFVZ8eXjfxCjsUXnVsV3PP9
I09rN4lMHBRujs45GNG0QlHzpMYauVhKvjnxh4Z0uu1F/C9U90rqpwdsf3fPet5z
r6nD5eYi
=NXdG
-----END PGP SIGNATURE-----
Based on suggestions by MarcoFalke <falke.marco@gmail.com>
e4aec1e
to
11daf6c
Compare
re-ACK 11daf6c Only change is removing a hunk in the tests 🌕 Show signatureSignature:
|
🐙 This pull request conflicts with the target branch and needs rebase. Want to unsubscribe from rebase notifications on this pull request? Just convert this pull request to a "draft". |
@@ -35,7 +35,7 @@ std::string static EncodeDumpString(const std::string &str) { | |||
std::stringstream ret; | |||
for (const unsigned char c : str) { | |||
if (c <= 32 || c >= 128 || c == '%') { | |||
ret << '%' << HexStr(Span<const unsigned char>(&c, 1)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If anyone is confused about the bot marking this as needing a rebase, and then the merge. The conflict was in src/wallet/rpcdump.cpp
. The conflicting code was moved from there, to src/wallet/rpc/backup.cpp
in #23647. You can see src/wallet/rpc/backup.cpp
being updated in the merge commit: 8b1de78#diff-c4eeb9bd8e84ac276465d100d6ac4c1c9b9ddc145827a03dfe11932598b028b9R38.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, daily reminder to stop trusting GitHub metadata
…ion guide 1d16571 More Span simplifications (Pieter Wuille) d692560 Replace MakeSpan helper with Span deduction guide (Pieter Wuille) Pull request description: C++17 supports [user-defined deduction guides](https://en.cppreference.com/w/cpp/language/class_template_argument_deduction), allowing class constructors to be invoked without specifying class template arguments. Instead, the code can contain rules to infer the template arguments from the constructor argument types. This alleviates the need for the `MakeSpan` helper. Convert the existing MakeSpan rules into deduction rules for `Span` itself, and replace all invocations of `MakeSpan` with just `Span` ones. ACKs for top commit: MarcoFalke: re-ACK 1d16571 Only change is removing a hunk in the tests 🌕 Tree-SHA512: 10f3e82e4338f39d9b7b407cd11aac7ebe1e9191b58e3d7f4e5e338a4636c0e126b4a1d912127c7446f57ba356c8d6544482e47f97901efea6a54fffbfd7895f
This is a backport of bitcoin/bitcoin#23413 > C++17 supports user-defined deduction guides, allowing class constructors > to be invoked without specifying class template arguments. Instead, the > code can contain rules to infer the template arguments from the > constructor argument types. > > This alleviates the need for the MakeSpan helper. Convert the existing > MakeSpan rules into deduction rules for Span itself, and replace all > invocations of MakeSpan with just Span ones. This addresses @cculianu's [comment regarding deduction guides replacing MakeSpan](https://gitlab.com/bitcoin-cash-node/bitcoin-cash-node/-/merge_requests/1411#note_798989348).
C++17 supports user-defined deduction guides, allowing class constructors to be invoked without specifying class template arguments. Instead, the code can contain rules to infer the template arguments from the constructor argument types.
This alleviates the need for the
MakeSpan
helper. Convert the existing MakeSpan rules into deduction rules forSpan
itself, and replace all invocations ofMakeSpan
with justSpan
ones.