mirror of
https://github.com/bitcoin/bitcoin.git
synced 2024-11-20 10:38:42 +01:00
Support deserializing into temporaries
Currently, the READWRITE macro cannot be passed any non-const temporaries, as the SerReadWrite function only accepts lvalue references. Deserializing into a temporary is very common, however. See for example things like 's >> VARINT(n)'. The VARINT macro produces a temporary wrapper that holds a reference to n. Fix this by accepting non-const rvalue references instead of lvalue references. We don't propagate the rvalue-ness down, as there are no useful optimizations that only apply to temporaries. Then use this new functionality to get rid of many (but not all) uses of the 'REF' macro (which casts away constness).
This commit is contained in:
parent
2761bca997
commit
172f5fa738
@ -90,11 +90,11 @@ public:
|
||||
while (txn.size() < txn_size) {
|
||||
txn.resize(std::min((uint64_t)(1000 + txn.size()), txn_size));
|
||||
for (; i < txn.size(); i++)
|
||||
READWRITE(REF(TransactionCompressor(txn[i])));
|
||||
READWRITE(TransactionCompressor(txn[i]));
|
||||
}
|
||||
} else {
|
||||
for (size_t i = 0; i < txn.size(); i++)
|
||||
READWRITE(REF(TransactionCompressor(txn[i])));
|
||||
READWRITE(TransactionCompressor(txn[i]));
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -115,7 +115,7 @@ struct PrefilledTransaction {
|
||||
if (idx > std::numeric_limits<uint16_t>::max())
|
||||
throw std::ios_base::failure("index overflowed 16-bits");
|
||||
index = idx;
|
||||
READWRITE(REF(TransactionCompressor(tx)));
|
||||
READWRITE(TransactionCompressor(tx));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -69,7 +69,7 @@ public:
|
||||
::Unserialize(s, VARINT(code));
|
||||
nHeight = code >> 1;
|
||||
fCoinBase = code & 1;
|
||||
::Unserialize(s, REF(CTxOutCompressor(out)));
|
||||
::Unserialize(s, CTxOutCompressor(out));
|
||||
}
|
||||
|
||||
bool IsSpent() const {
|
||||
|
@ -73,7 +73,7 @@ public:
|
||||
s >> VARINT(nSize);
|
||||
if (nSize < nSpecialScripts) {
|
||||
std::vector<unsigned char> vch(GetSpecialSize(nSize), 0x00);
|
||||
s >> REF(CFlatData(vch));
|
||||
s >> CFlatData(vch);
|
||||
Decompress(nSize, vch);
|
||||
return;
|
||||
}
|
||||
@ -84,7 +84,7 @@ public:
|
||||
s.ignore(nSize);
|
||||
} else {
|
||||
script.resize(nSize);
|
||||
s >> REF(CFlatData(script));
|
||||
s >> CFlatData(script);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -173,7 +173,7 @@ public:
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
CHashVerifier<Source>& operator>>(T& obj)
|
||||
CHashVerifier<Source>& operator>>(T&& obj)
|
||||
{
|
||||
// Unserialize from this stream
|
||||
::Unserialize(*this, obj);
|
||||
|
@ -40,7 +40,7 @@ public:
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
TxInputStream& operator>>(T& obj)
|
||||
TxInputStream& operator>>(T&& obj)
|
||||
{
|
||||
::Unserialize(*this, obj);
|
||||
return *this;
|
||||
|
@ -350,10 +350,10 @@ I ReadVarInt(Stream& is)
|
||||
}
|
||||
}
|
||||
|
||||
#define FLATDATA(obj) REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj)))
|
||||
#define VARINT(obj) REF(WrapVarInt(REF(obj)))
|
||||
#define COMPACTSIZE(obj) REF(CCompactSize(REF(obj)))
|
||||
#define LIMITED_STRING(obj,n) REF(LimitedString< n >(REF(obj)))
|
||||
#define FLATDATA(obj) CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj))
|
||||
#define VARINT(obj) WrapVarInt(REF(obj))
|
||||
#define COMPACTSIZE(obj) CCompactSize(REF(obj))
|
||||
#define LIMITED_STRING(obj,n) LimitedString< n >(REF(obj))
|
||||
|
||||
/**
|
||||
* Wrapper for serializing arrays and POD.
|
||||
@ -538,7 +538,7 @@ inline void Serialize(Stream& os, const T& a)
|
||||
}
|
||||
|
||||
template<typename Stream, typename T>
|
||||
inline void Unserialize(Stream& is, T& a)
|
||||
inline void Unserialize(Stream& is, T&& a)
|
||||
{
|
||||
a.Unserialize(is);
|
||||
}
|
||||
@ -884,10 +884,10 @@ void SerializeMany(Stream& s)
|
||||
}
|
||||
|
||||
template<typename Stream, typename Arg, typename... Args>
|
||||
void SerializeMany(Stream& s, Arg&& arg, Args&&... args)
|
||||
void SerializeMany(Stream& s, const Arg& arg, const Args&... args)
|
||||
{
|
||||
::Serialize(s, std::forward<Arg>(arg));
|
||||
::SerializeMany(s, std::forward<Args>(args)...);
|
||||
::Serialize(s, arg);
|
||||
::SerializeMany(s, args...);
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
@ -896,20 +896,20 @@ inline void UnserializeMany(Stream& s)
|
||||
}
|
||||
|
||||
template<typename Stream, typename Arg, typename... Args>
|
||||
inline void UnserializeMany(Stream& s, Arg& arg, Args&... args)
|
||||
inline void UnserializeMany(Stream& s, Arg&& arg, Args&&... args)
|
||||
{
|
||||
::Unserialize(s, arg);
|
||||
::UnserializeMany(s, args...);
|
||||
}
|
||||
|
||||
template<typename Stream, typename... Args>
|
||||
inline void SerReadWriteMany(Stream& s, CSerActionSerialize ser_action, Args&&... args)
|
||||
inline void SerReadWriteMany(Stream& s, CSerActionSerialize ser_action, const Args&... args)
|
||||
{
|
||||
::SerializeMany(s, std::forward<Args>(args)...);
|
||||
::SerializeMany(s, args...);
|
||||
}
|
||||
|
||||
template<typename Stream, typename... Args>
|
||||
inline void SerReadWriteMany(Stream& s, CSerActionUnserialize ser_action, Args&... args)
|
||||
inline void SerReadWriteMany(Stream& s, CSerActionUnserialize ser_action, Args&&... args)
|
||||
{
|
||||
::UnserializeMany(s, args...);
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ public:
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
OverrideStream<Stream>& operator>>(T& obj)
|
||||
OverrideStream<Stream>& operator>>(T&& obj)
|
||||
{
|
||||
// Unserialize from this stream
|
||||
::Unserialize(*this, obj);
|
||||
@ -399,7 +399,7 @@ public:
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
CDataStream& operator>>(T& obj)
|
||||
CDataStream& operator>>(T&& obj)
|
||||
{
|
||||
// Unserialize from this stream
|
||||
::Unserialize(*this, obj);
|
||||
@ -543,7 +543,7 @@ public:
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
CAutoFile& operator>>(T& obj)
|
||||
CAutoFile& operator>>(T&& obj)
|
||||
{
|
||||
// Unserialize from this stream
|
||||
if (!file)
|
||||
@ -686,7 +686,7 @@ public:
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
CBufferedFile& operator>>(T& obj) {
|
||||
CBufferedFile& operator>>(T&& obj) {
|
||||
// Unserialize from this stream
|
||||
::Unserialize(*this, obj);
|
||||
return (*this);
|
||||
|
@ -348,7 +348,7 @@ public:
|
||||
vout.assign(vAvail.size(), CTxOut());
|
||||
for (unsigned int i = 0; i < vAvail.size(); i++) {
|
||||
if (vAvail[i])
|
||||
::Unserialize(s, REF(CTxOutCompressor(vout[i])));
|
||||
::Unserialize(s, CTxOutCompressor(vout[i]));
|
||||
}
|
||||
// coinbase height
|
||||
::Unserialize(s, VARINT(nHeight));
|
||||
|
@ -54,7 +54,7 @@ public:
|
||||
int nVersionDummy;
|
||||
::Unserialize(s, VARINT(nVersionDummy));
|
||||
}
|
||||
::Unserialize(s, REF(CTxOutCompressor(REF(txout->out))));
|
||||
::Unserialize(s, CTxOutCompressor(REF(txout->out)));
|
||||
}
|
||||
|
||||
explicit TxInUndoDeserializer(Coin* coin) : txout(coin) {}
|
||||
@ -76,7 +76,7 @@ public:
|
||||
uint64_t count = vprevout.size();
|
||||
::Serialize(s, COMPACTSIZE(REF(count)));
|
||||
for (const auto& prevout : vprevout) {
|
||||
::Serialize(s, REF(TxInUndoSerializer(&prevout)));
|
||||
::Serialize(s, TxInUndoSerializer(&prevout));
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,7 +90,7 @@ public:
|
||||
}
|
||||
vprevout.resize(count);
|
||||
for (auto& prevout : vprevout) {
|
||||
::Unserialize(s, REF(TxInUndoDeserializer(&prevout)));
|
||||
::Unserialize(s, TxInUndoDeserializer(&prevout));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user