diff options
| author | Wladimir J. van der Laan <[email protected]> | 2018-04-10 19:56:22 +0200 |
|---|---|---|
| committer | Wladimir J. van der Laan <[email protected]> | 2018-04-10 20:54:33 +0200 |
| commit | 0a8054e7cd5c76d01e4ac7234e3883d05f6f5fdd (patch) | |
| tree | ff45a44e6f9bf3a76df3f5f23a80208b550d7a96 | |
| parent | Merge #12749: [wallet] feebumper: discard change outputs below discard rate (diff) | |
| parent | Support serialization as another type without casting (diff) | |
| download | discoin-0a8054e7cd5c76d01e4ac7234e3883d05f6f5fdd.tar.xz discoin-0a8054e7cd5c76d01e4ac7234e3883d05f6f5fdd.zip | |
Merge #12731: Support serialization as another type without casting
818dc74 Support serialization as another type without casting (Pieter Wuille)
Pull request description:
This adds a `READWRITEAS(type, obj)` macro which serializes `obj` as if it were converted to `const type&` when `const`, and to `type&` when non-`const`. No actual cast is involved, so this only works when this conversion can be done automatically.
This makes it usable in serialization code that uses a single implementation for both serialization and deserializing, which doesn't know the constness of the object involved.
This is a redo of #12712, using a slightly different interface.
Tree-SHA512: 262f0257284ff99b5ffaec9b997c194e221522ba35c3ac8eaa9bb344449d7ea0a314de254dc77449fa7aaa600f8cd9a24da65aade8c1ec6aa80c6e9a7bba5ca7
| -rw-r--r-- | src/addrman.h | 2 | ||||
| -rw-r--r-- | src/primitives/block.h | 2 | ||||
| -rw-r--r-- | src/protocol.h | 2 | ||||
| -rw-r--r-- | src/script/script.h | 2 | ||||
| -rw-r--r-- | src/serialize.h | 7 | ||||
| -rw-r--r-- | src/txdb.h | 2 | ||||
| -rw-r--r-- | src/wallet/wallet.h | 4 |
7 files changed, 13 insertions, 8 deletions
diff --git a/src/addrman.h b/src/addrman.h index 6dec3fe41..a36f7ea10 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -59,7 +59,7 @@ public: template <typename Stream, typename Operation> inline void SerializationOp(Stream& s, Operation ser_action) { - READWRITE(*static_cast<CAddress*>(this)); + READWRITEAS(CAddress, *this); READWRITE(source); READWRITE(nLastSuccess); READWRITE(nAttempts); diff --git a/src/primitives/block.h b/src/primitives/block.h index 5d6d44ac7..1fca55d91 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -93,7 +93,7 @@ public: template <typename Stream, typename Operation> inline void SerializationOp(Stream& s, Operation ser_action) { - READWRITE(*static_cast<CBlockHeader*>(this)); + READWRITEAS(CBlockHeader, *this); READWRITE(vtx); } diff --git a/src/protocol.h b/src/protocol.h index a07c5ea86..3a9b2d256 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -349,7 +349,7 @@ public: uint64_t nServicesInt = nServices; READWRITE(nServicesInt); nServices = static_cast<ServiceFlags>(nServicesInt); - READWRITE(*static_cast<CService*>(this)); + READWRITEAS(CService, *this); } // TODO: make private (improves encapsulation) diff --git a/src/script/script.h b/src/script/script.h index 591777672..8e5a792c7 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -415,7 +415,7 @@ public: template <typename Stream, typename Operation> inline void SerializationOp(Stream& s, Operation ser_action) { - READWRITE(static_cast<CScriptBase&>(*this)); + READWRITEAS(CScriptBase, *this); } CScript& operator+=(const CScript& b) diff --git a/src/serialize.h b/src/serialize.h index e90b041cc..57e434faf 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -155,7 +155,12 @@ enum SER_GETHASH = (1 << 2), }; -#define READWRITE(...) (::SerReadWriteMany(s, ser_action, __VA_ARGS__)) +//! Convert the reference base type to X, without changing constness or reference type. +template<typename X> X& ReadWriteAsHelper(X& x) { return x; } +template<typename X> const X& ReadWriteAsHelper(const X& x) { return x; } + +#define READWRITE(...) (::SerReadWriteMany(s, ser_action, __VA_ARGS__)) +#define READWRITEAS(type, obj) (::SerReadWriteMany(s, ser_action, ReadWriteAsHelper<type>(obj))) /** * Implement three methods for serializable objects. These are actually wrappers over diff --git a/src/txdb.h b/src/txdb.h index ad76b3257..f3454e7d0 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -47,7 +47,7 @@ struct CDiskTxPos : public CDiskBlockPos template <typename Stream, typename Operation> inline void SerializationOp(Stream& s, Operation ser_action) { - READWRITE(*static_cast<CDiskBlockPos*>(this)); + READWRITEAS(CDiskBlockPos, *this); READWRITE(VARINT(nTxOffset)); } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 170e60d48..d66e3e481 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -396,7 +396,7 @@ public: mapValueCopy["timesmart"] = strprintf("%u", nTimeSmart); } - s << *static_cast<const CMerkleTx*>(this); + s << static_cast<const CMerkleTx&>(*this); std::vector<CMerkleTx> vUnused; //!< Used to be vtxPrev s << vUnused << mapValueCopy << vOrderForm << fTimeReceivedIsTxTime << nTimeReceived << fFromMe << fSpent; } @@ -407,7 +407,7 @@ public: Init(nullptr); char fSpent; - s >> *static_cast<CMerkleTx*>(this); + s >> static_cast<CMerkleTx&>(*this); std::vector<CMerkleTx> vUnused; //!< Used to be vtxPrev s >> vUnused >> mapValue >> vOrderForm >> fTimeReceivedIsTxTime >> nTimeReceived >> fFromMe >> fSpent; |