Skip to content

Commit aaaa3fa

Browse files
MarcoFalkesipa
andcommitted
Replace READWRITEAS macro with AsBase wrapping function
Co-authored-by: Pieter Wuille <[email protected]>
1 parent 1c1a02b commit aaaa3fa

File tree

7 files changed

+38
-14
lines changed

7 files changed

+38
-14
lines changed

src/addrman_impl.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,7 @@ class AddrInfo : public CAddress
6565

6666
SERIALIZE_METHODS(AddrInfo, obj)
6767
{
68-
READWRITEAS(CAddress, obj);
69-
READWRITE(obj.source, Using<ChronoFormatter<int64_t>>(obj.m_last_success), obj.nAttempts);
68+
READWRITE(AsBase<CAddress>(obj), obj.source, Using<ChronoFormatter<int64_t>>(obj.m_last_success), obj.nAttempts);
7069
}
7170

7271
AddrInfo(const CAddress &addrIn, const CNetAddr &addrSource) : CAddress(addrIn), source(addrSource)

src/index/disktxpos.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ struct CDiskTxPos : public FlatFilePos
1414

1515
SERIALIZE_METHODS(CDiskTxPos, obj)
1616
{
17-
READWRITEAS(FlatFilePos, obj);
18-
READWRITE(VARINT(obj.nTxOffset));
17+
READWRITE(AsBase<FlatFilePos>(obj), VARINT(obj.nTxOffset));
1918
}
2019

2120
CDiskTxPos(const FlatFilePos &blockIn, unsigned int nTxOffsetIn) : FlatFilePos(blockIn.nFile, blockIn.nPos), nTxOffset(nTxOffsetIn) {

src/netaddress.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -540,8 +540,7 @@ class CService : public CNetAddr
540540

541541
SERIALIZE_METHODS(CService, obj)
542542
{
543-
READWRITEAS(CNetAddr, obj);
544-
READWRITE(Using<BigEndianFormatter<2>>(obj.port));
543+
READWRITE(AsBase<CNetAddr>(obj), Using<BigEndianFormatter<2>>(obj.port));
545544
}
546545

547546
friend class CServiceHash;

src/primitives/block.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,7 @@ class CBlock : public CBlockHeader
8787

8888
SERIALIZE_METHODS(CBlock, obj)
8989
{
90-
READWRITEAS(CBlockHeader, obj);
91-
READWRITE(obj.vtx);
90+
READWRITE(AsBase<CBlockHeader>(obj), obj.vtx);
9291
}
9392

9493
void SetNull()

src/protocol.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ class CAddress : public CService
433433
}
434434
// Invoke V1/V2 serializer for CService parent object.
435435
OverrideStream<Stream> os(&s, s.GetType(), use_v2 ? ADDRV2_FORMAT : 0);
436-
SerReadWriteMany(os, ser_action, ReadWriteAsHelper<CService>(obj));
436+
SerReadWriteMany(os, ser_action, AsBase<CService>(obj));
437437
}
438438

439439
//! Always included in serialization. The behavior is unspecified if the value is not representable as uint32_t.

src/script/script.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ class CScript : public CScriptBase
434434
CScript(std::vector<unsigned char>::const_iterator pbegin, std::vector<unsigned char>::const_iterator pend) : CScriptBase(pbegin, pend) { }
435435
CScript(const unsigned char* pbegin, const unsigned char* pend) : CScriptBase(pbegin, pend) { }
436436

437-
SERIALIZE_METHODS(CScript, obj) { READWRITEAS(CScriptBase, obj); }
437+
SERIALIZE_METHODS(CScript, obj) { READWRITE(AsBase<CScriptBase>(obj)); }
438438

439439
explicit CScript(int64_t b) { operator<<(b); }
440440
explicit CScript(opcodetype b) { operator<<(b); }

src/serialize.h

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -133,12 +133,40 @@ enum
133133
SER_GETHASH = (1 << 2),
134134
};
135135

136-
//! Convert the reference base type to X, without changing constness or reference type.
137-
template<typename X> X& ReadWriteAsHelper(X& x) { return x; }
138-
template<typename X> const X& ReadWriteAsHelper(const X& x) { return x; }
136+
/**
137+
* Convert any argument to a reference to X, maintaining constness.
138+
*
139+
* This can be used in serialization code to invoke a base class's
140+
* serialization routines.
141+
*
142+
* Example use:
143+
* class Base { ... };
144+
* class Child : public Base {
145+
* int m_data;
146+
* public:
147+
* SERIALIZE_METHODS(Child, obj) {
148+
* READWRITE(AsBase<Base>(obj), obj.m_data);
149+
* }
150+
* };
151+
*
152+
* static_cast cannot easily be used here, as the type of Obj will be const Child&
153+
* during serialization and Child& during deserialization. AsBase will convert to
154+
* const Base& and Base& appropriately.
155+
*/
156+
template <class Out, class In>
157+
Out& AsBase(In& x)
158+
{
159+
static_assert(std::is_base_of_v<Out, In>);
160+
return x;
161+
}
162+
template <class Out, class In>
163+
const Out& AsBase(const In& x)
164+
{
165+
static_assert(std::is_base_of_v<Out, In>);
166+
return x;
167+
}
139168

140169
#define READWRITE(...) (::SerReadWriteMany(s, ser_action, __VA_ARGS__))
141-
#define READWRITEAS(type, obj) (::SerReadWriteMany(s, ser_action, ReadWriteAsHelper<type>(obj)))
142170
#define SER_READ(obj, code) ::SerRead(s, ser_action, obj, [&](Stream& s, typename std::remove_const<Type>::type& obj) { code; })
143171
#define SER_WRITE(obj, code) ::SerWrite(s, ser_action, obj, [&](Stream& s, const Type& obj) { code; })
144172

0 commit comments

Comments
 (0)