diff options
author | fanquake <fanquake@gmail.com> | 2023-10-31 10:51:37 +0000 |
---|---|---|
committer | fanquake <fanquake@gmail.com> | 2023-10-31 11:11:25 +0000 |
commit | d51fb9caa622add96c6b594e162da5584eb927fc (patch) | |
tree | 3b123d191897ddd1740296698e8df373337656a5 /src | |
parent | 4458ae811a264968c2a7ea4bb7050eed492a7e36 (diff) | |
parent | 99990194ce26af89308fab5ad0b1c8c26e45f80c (diff) |
Merge bitcoin/bitcoin#28503: refactor: Remove WithParams serialization helper, use SER_PARAMS_OPFUNC
99990194ce26af89308fab5ad0b1c8c26e45f80c Remove WithParams serialization helper (MarcoFalke)
ffffb4af83a47979a0ecc84247bc1167abc2fbf6 scripted-diff: Use ser params operator (MarcoFalke)
fae9054793ff2a15db1a645cce3df749e0de2f39 test: Use SER_PARAMS_OPFUNC in serialize_tests.cpp (MarcoFalke)
Pull request description:
Every serialization parameter struct already has the `SER_PARAMS_OPFUNC`, except for one in the tests.
For consistency, and to remove verbose code, convert the test to `SER_PARAMS_OPFUNC`, and use it everywhere, then remove the `WithParams` helper.
ACKs for top commit:
ajtowns:
reACK 99990194ce26af89308fab5ad0b1c8c26e45f80c
TheCharlatan:
Re-ACK 99990194ce26af89308fab5ad0b1c8c26e45f80c
Tree-SHA512: be9cae4225a502486fe8d552aaf4b2cd2904a9f73cce9d931c6b7c757594ff1982fcc2c30d00d012cd12b0a9531fd609f8bcd7c94b811e965ac087eb8a3589d3
Diffstat (limited to 'src')
-rw-r--r-- | src/net_processing.cpp | 12 | ||||
-rw-r--r-- | src/protocol.h | 2 | ||||
-rw-r--r-- | src/serialize.h | 31 | ||||
-rw-r--r-- | src/test/fuzz/deserialize.cpp | 6 | ||||
-rw-r--r-- | src/test/fuzz/util.h | 2 | ||||
-rw-r--r-- | src/test/net_tests.cpp | 60 | ||||
-rw-r--r-- | src/test/serialize_tests.cpp | 48 |
7 files changed, 79 insertions, 82 deletions
diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 7fcc399151..2f41eb2b1d 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -3770,7 +3770,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type, std::vector<CAddress> vAddr; - vRecv >> WithParams(ser_params, vAddr); + vRecv >> ser_params(vAddr); if (!SetupAddressRelay(pfrom, *peer)) { LogPrint(BCLog::NET, "ignoring %s message from %s peer=%d\n", msg_type, pfrom.ConnectionTypeAsString(), pfrom.GetId()); @@ -5375,16 +5375,12 @@ void PeerManagerImpl::MaybeSendAddr(CNode& node, Peer& peer, std::chrono::micros // No addr messages to send if (peer.m_addrs_to_send.empty()) return; - const char* msg_type; - CNetAddr::Encoding ser_enc; + CNetMsgMaker mm(node.GetCommonVersion()); if (peer.m_wants_addrv2) { - msg_type = NetMsgType::ADDRV2; - ser_enc = CNetAddr::Encoding::V2; + m_connman.PushMessage(&node, mm.Make(NetMsgType::ADDRV2, CAddress::V2_NETWORK(peer.m_addrs_to_send))); } else { - msg_type = NetMsgType::ADDR; - ser_enc = CNetAddr::Encoding::V1; + m_connman.PushMessage(&node, mm.Make(NetMsgType::ADDR, CAddress::V1_NETWORK(peer.m_addrs_to_send))); } - m_connman.PushMessage(&node, CNetMsgMaker(node.GetCommonVersion()).Make(msg_type, WithParams(CAddress::SerParams{{ser_enc}, CAddress::Format::Network}, peer.m_addrs_to_send))); peer.m_addrs_to_send.clear(); // we only send the big addr message once diff --git a/src/protocol.h b/src/protocol.h index a58d671a70..e405253632 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -445,7 +445,7 @@ public: } // Invoke V1/V2 serializer for CService parent object. const auto ser_params{use_v2 ? CNetAddr::V2 : CNetAddr::V1}; - READWRITE(WithParams(ser_params, AsBase<CService>(obj))); + READWRITE(ser_params(AsBase<CService>(obj))); } //! Always included in serialization. The behavior is unspecified if the value is not representable as uint32_t. diff --git a/src/serialize.h b/src/serialize.h index 8b15178ec0..b09d6fbe60 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -214,11 +214,11 @@ const Out& AsBase(const In& x) * } * }; * which would then be invoked as - * READWRITE(WithParams(BarParameter{...}, Using<FooFormatter>(obj.foo))) + * READWRITE(BarParameter{...}(Using<FooFormatter>(obj.foo))) * - * WithParams(parameter, obj) can be invoked anywhere in the call stack; it is + * parameter(obj) can be invoked anywhere in the call stack; it is * passed down recursively into all serialization code, until another - * WithParams overrides it. + * serialization parameter overrides it. * * Parameters will be implicitly converted where appropriate. This means that * "parent" serialization code can use a parameter that derives from, or is @@ -1183,17 +1183,6 @@ public: }; /** - * Return a wrapper around t that (de)serializes it with specified parameter params. - * - * See FORMATTER_METHODS_PARAMS for more information on serialization parameters. - */ -template <typename Params, typename T> -static auto WithParams(const Params& params, T&& t) -{ - return ParamsWrapper<Params, T>{params, t}; -} - -/** * Helper macro for SerParams structs * * Allows you define SerParams instances and then apply them directly @@ -1202,8 +1191,16 @@ static auto WithParams(const Params& params, T&& t) * constexpr SerParams FOO{....}; * ss << FOO(obj); */ -#define SER_PARAMS_OPFUNC \ - template <typename T> \ - auto operator()(T&& t) const { return WithParams(*this, t); } +#define SER_PARAMS_OPFUNC \ + /** \ + * Return a wrapper around t that (de)serializes it with specified parameter params. \ + * \ + * See FORMATTER_METHODS_PARAMS for more information on serialization parameters. \ + */ \ + template <typename T> \ + auto operator()(T&& t) const \ + { \ + return ParamsWrapper{*this, t}; \ + } #endif // BITCOIN_SERIALIZE_H diff --git a/src/test/fuzz/deserialize.cpp b/src/test/fuzz/deserialize.cpp index 510ee7fb5b..abc230c07d 100644 --- a/src/test/fuzz/deserialize.cpp +++ b/src/test/fuzz/deserialize.cpp @@ -66,7 +66,7 @@ template <typename T, typename P> DataStream Serialize(const T& obj, const P& params) { DataStream ds{}; - ds << WithParams(params, obj); + ds << params(obj); return ds; } @@ -74,7 +74,7 @@ template <typename T, typename P> T Deserialize(DataStream&& ds, const P& params) { T obj; - ds >> WithParams(params, obj); + ds >> params(obj); return obj; } @@ -83,7 +83,7 @@ void DeserializeFromFuzzingInput(FuzzBufferType buffer, T&& obj, const P& params { DataStream ds{buffer}; try { - ds >> WithParams(params, obj); + ds >> params(obj); } catch (const std::ios_base::failure&) { throw invalid_fuzzing_input_exception(); } diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h index 8263cd4c08..95d910b64d 100644 --- a/src/test/fuzz/util.h +++ b/src/test/fuzz/util.h @@ -107,7 +107,7 @@ template <typename T, typename P> DataStream ds{buffer}; T obj; try { - ds >> WithParams(params, obj); + ds >> params(obj); } catch (const std::ios_base::failure&) { return std::nullopt; } diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp index 7c98c382e4..48e0706a53 100644 --- a/src/test/net_tests.cpp +++ b/src/test/net_tests.cpp @@ -331,17 +331,17 @@ BOOST_AUTO_TEST_CASE(cnetaddr_serialize_v1) DataStream s{}; const auto ser_params{CAddress::V1_NETWORK}; - s << WithParams(ser_params, addr); + s << ser_params(addr); BOOST_CHECK_EQUAL(HexStr(s), "00000000000000000000000000000000"); s.clear(); addr = LookupHost("1.2.3.4", false).value(); - s << WithParams(ser_params, addr); + s << ser_params(addr); BOOST_CHECK_EQUAL(HexStr(s), "00000000000000000000ffff01020304"); s.clear(); addr = LookupHost("1a1b:2a2b:3a3b:4a4b:5a5b:6a6b:7a7b:8a8b", false).value(); - s << WithParams(ser_params, addr); + s << ser_params(addr); BOOST_CHECK_EQUAL(HexStr(s), "1a1b2a2b3a3b4a4b5a5b6a6b7a7b8a8b"); s.clear(); @@ -349,12 +349,12 @@ BOOST_AUTO_TEST_CASE(cnetaddr_serialize_v1) BOOST_CHECK(!addr.SetSpecial("6hzph5hv6337r6p2.onion")); BOOST_REQUIRE(addr.SetSpecial("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion")); - s << WithParams(ser_params, addr); + s << ser_params(addr); BOOST_CHECK_EQUAL(HexStr(s), "00000000000000000000000000000000"); s.clear(); addr.SetInternal("a"); - s << WithParams(ser_params, addr); + s << ser_params(addr); BOOST_CHECK_EQUAL(HexStr(s), "fd6b88c08724ca978112ca1bbdcafac2"); s.clear(); } @@ -365,17 +365,17 @@ BOOST_AUTO_TEST_CASE(cnetaddr_serialize_v2) DataStream s{}; const auto ser_params{CAddress::V2_NETWORK}; - s << WithParams(ser_params, addr); + s << ser_params(addr); BOOST_CHECK_EQUAL(HexStr(s), "021000000000000000000000000000000000"); s.clear(); addr = LookupHost("1.2.3.4", false).value(); - s << WithParams(ser_params, addr); + s << ser_params(addr); BOOST_CHECK_EQUAL(HexStr(s), "010401020304"); s.clear(); addr = LookupHost("1a1b:2a2b:3a3b:4a4b:5a5b:6a6b:7a7b:8a8b", false).value(); - s << WithParams(ser_params, addr); + s << ser_params(addr); BOOST_CHECK_EQUAL(HexStr(s), "02101a1b2a2b3a3b4a4b5a5b6a6b7a7b8a8b"); s.clear(); @@ -383,12 +383,12 @@ BOOST_AUTO_TEST_CASE(cnetaddr_serialize_v2) BOOST_CHECK(!addr.SetSpecial("6hzph5hv6337r6p2.onion")); BOOST_REQUIRE(addr.SetSpecial("kpgvmscirrdqpekbqjsvw5teanhatztpp2gl6eee4zkowvwfxwenqaid.onion")); - s << WithParams(ser_params, addr); + s << ser_params(addr); BOOST_CHECK_EQUAL(HexStr(s), "042053cd5648488c4707914182655b7664034e09e66f7e8cbf1084e654eb56c5bd88"); s.clear(); BOOST_REQUIRE(addr.SetInternal("a")); - s << WithParams(ser_params, addr); + s << ser_params(addr); BOOST_CHECK_EQUAL(HexStr(s), "0210fd6b88c08724ca978112ca1bbdcafac2"); s.clear(); } @@ -403,7 +403,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2) s << Span{ParseHex("01" // network type (IPv4) "04" // address length "01020304")}; // address - s >> WithParams(ser_params, addr); + s >> ser_params(addr); BOOST_CHECK(addr.IsValid()); BOOST_CHECK(addr.IsIPv4()); BOOST_CHECK(addr.IsAddrV1Compatible()); @@ -414,7 +414,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2) s << Span{ParseHex("01" // network type (IPv4) "04" // address length "0102")}; // address - BOOST_CHECK_EXCEPTION(s >> WithParams(ser_params, addr), std::ios_base::failure, HasReason("end of data")); + BOOST_CHECK_EXCEPTION(s >> ser_params(addr), std::ios_base::failure, HasReason("end of data")); BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input. s.clear(); @@ -422,7 +422,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2) s << Span{ParseHex("01" // network type (IPv4) "05" // address length "01020304")}; // address - BOOST_CHECK_EXCEPTION(s >> WithParams(ser_params, addr), std::ios_base::failure, + BOOST_CHECK_EXCEPTION(s >> ser_params(addr), std::ios_base::failure, HasReason("BIP155 IPv4 address with length 5 (should be 4)")); BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input. s.clear(); @@ -431,7 +431,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2) s << Span{ParseHex("01" // network type (IPv4) "fd0102" // address length (513 as CompactSize) "01020304")}; // address - BOOST_CHECK_EXCEPTION(s >> WithParams(ser_params, addr), std::ios_base::failure, + BOOST_CHECK_EXCEPTION(s >> ser_params(addr), std::ios_base::failure, HasReason("Address too long: 513 > 512")); BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input. s.clear(); @@ -440,7 +440,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2) s << Span{ParseHex("02" // network type (IPv6) "10" // address length "0102030405060708090a0b0c0d0e0f10")}; // address - s >> WithParams(ser_params, addr); + s >> ser_params(addr); BOOST_CHECK(addr.IsValid()); BOOST_CHECK(addr.IsIPv6()); BOOST_CHECK(addr.IsAddrV1Compatible()); @@ -453,7 +453,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2) "10" // address length "fd6b88c08724ca978112ca1bbdcafac2")}; // address: 0xfd + sha256("bitcoin")[0:5] + // sha256(name)[0:10] - s >> WithParams(ser_params, addr); + s >> ser_params(addr); BOOST_CHECK(addr.IsInternal()); BOOST_CHECK(addr.IsAddrV1Compatible()); BOOST_CHECK_EQUAL(addr.ToStringAddr(), "zklycewkdo64v6wc.internal"); @@ -463,7 +463,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2) s << Span{ParseHex("02" // network type (IPv6) "04" // address length "00")}; // address - BOOST_CHECK_EXCEPTION(s >> WithParams(ser_params, addr), std::ios_base::failure, + BOOST_CHECK_EXCEPTION(s >> ser_params(addr), std::ios_base::failure, HasReason("BIP155 IPv6 address with length 4 (should be 16)")); BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input. s.clear(); @@ -472,7 +472,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2) s << Span{ParseHex("02" // network type (IPv6) "10" // address length "00000000000000000000ffff01020304")}; // address - s >> WithParams(ser_params, addr); + s >> ser_params(addr); BOOST_CHECK(!addr.IsValid()); BOOST_REQUIRE(s.empty()); @@ -480,7 +480,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2) s << Span{ParseHex("02" // network type (IPv6) "10" // address length "fd87d87eeb430102030405060708090a")}; // address - s >> WithParams(ser_params, addr); + s >> ser_params(addr); BOOST_CHECK(!addr.IsValid()); BOOST_REQUIRE(s.empty()); @@ -488,7 +488,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2) s << Span{ParseHex("03" // network type (TORv2) "0a" // address length "f1f2f3f4f5f6f7f8f9fa")}; // address - s >> WithParams(ser_params, addr); + s >> ser_params(addr); BOOST_CHECK(!addr.IsValid()); BOOST_REQUIRE(s.empty()); @@ -498,7 +498,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2) "79bcc625184b05194975c28b66b66b04" // address "69f7f6556fb1ac3189a79b40dda32f1f" )}; - s >> WithParams(ser_params, addr); + s >> ser_params(addr); BOOST_CHECK(addr.IsValid()); BOOST_CHECK(addr.IsTor()); BOOST_CHECK(!addr.IsAddrV1Compatible()); @@ -511,7 +511,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2) "00" // address length "00" // address )}; - BOOST_CHECK_EXCEPTION(s >> WithParams(ser_params, addr), std::ios_base::failure, + BOOST_CHECK_EXCEPTION(s >> ser_params(addr), std::ios_base::failure, HasReason("BIP155 TORv3 address with length 0 (should be 32)")); BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input. s.clear(); @@ -521,7 +521,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2) "20" // address length "a2894dabaec08c0051a481a6dac88b64" // address "f98232ae42d4b6fd2fa81952dfe36a87")}; - s >> WithParams(ser_params, addr); + s >> ser_params(addr); BOOST_CHECK(addr.IsValid()); BOOST_CHECK(addr.IsI2P()); BOOST_CHECK(!addr.IsAddrV1Compatible()); @@ -534,7 +534,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2) "03" // address length "00" // address )}; - BOOST_CHECK_EXCEPTION(s >> WithParams(ser_params, addr), std::ios_base::failure, + BOOST_CHECK_EXCEPTION(s >> ser_params(addr), std::ios_base::failure, HasReason("BIP155 I2P address with length 3 (should be 32)")); BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input. s.clear(); @@ -544,7 +544,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2) "10" // address length "fc000001000200030004000500060007" // address )}; - s >> WithParams(ser_params, addr); + s >> ser_params(addr); BOOST_CHECK(addr.IsValid()); BOOST_CHECK(addr.IsCJDNS()); BOOST_CHECK(!addr.IsAddrV1Compatible()); @@ -556,7 +556,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2) "10" // address length "aa000001000200030004000500060007" // address )}; - s >> WithParams(ser_params, addr); + s >> ser_params(addr); BOOST_CHECK(addr.IsCJDNS()); BOOST_CHECK(!addr.IsValid()); BOOST_REQUIRE(s.empty()); @@ -566,7 +566,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2) "01" // address length "00" // address )}; - BOOST_CHECK_EXCEPTION(s >> WithParams(ser_params, addr), std::ios_base::failure, + BOOST_CHECK_EXCEPTION(s >> ser_params(addr), std::ios_base::failure, HasReason("BIP155 CJDNS address with length 1 (should be 16)")); BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input. s.clear(); @@ -576,7 +576,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2) "fe00000002" // address length (CompactSize's MAX_SIZE) "01020304050607" // address )}; - BOOST_CHECK_EXCEPTION(s >> WithParams(ser_params, addr), std::ios_base::failure, + BOOST_CHECK_EXCEPTION(s >> ser_params(addr), std::ios_base::failure, HasReason("Address too long: 33554432 > 512")); BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input. s.clear(); @@ -586,7 +586,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2) "04" // address length "01020304" // address )}; - s >> WithParams(ser_params, addr); + s >> ser_params(addr); BOOST_CHECK(!addr.IsValid()); BOOST_REQUIRE(s.empty()); @@ -595,7 +595,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2) "00" // address length "" // address )}; - s >> WithParams(ser_params, addr); + s >> ser_params(addr); BOOST_CHECK(!addr.IsValid()); BOOST_REQUIRE(s.empty()); } diff --git a/src/test/serialize_tests.cpp b/src/test/serialize_tests.cpp index d18d2623b1..49827be559 100644 --- a/src/test/serialize_tests.cpp +++ b/src/test/serialize_tests.cpp @@ -255,10 +255,15 @@ BOOST_AUTO_TEST_CASE(class_methods) } } -enum class BaseFormat { - RAW, - HEX, +struct BaseFormat { + const enum { + RAW, + HEX, + } m_base_format; + SER_PARAMS_OPFUNC }; +constexpr BaseFormat RAW{BaseFormat::RAW}; +constexpr BaseFormat HEX{BaseFormat::HEX}; /// (Un)serialize a number as raw byte or 2 hexadecimal chars. class Base @@ -272,7 +277,7 @@ public: template <typename Stream> void Serialize(Stream& s) const { - if (s.GetParams() == BaseFormat::RAW) { + if (s.GetParams().m_base_format == BaseFormat::RAW) { s << m_base_data; } else { s << Span{HexStr(Span{&m_base_data, 1})}; @@ -282,7 +287,7 @@ public: template <typename Stream> void Unserialize(Stream& s) { - if (s.GetParams() == BaseFormat::RAW) { + if (s.GetParams().m_base_format == BaseFormat::RAW) { s >> m_base_data; } else { std::string hex{"aa"}; @@ -301,6 +306,8 @@ public: LOWER, UPPER, } m_derived_format; + + SER_PARAMS_OPFUNC }; class Derived : public Base @@ -310,7 +317,7 @@ public: SERIALIZE_METHODS_PARAMS(Derived, obj, DerivedAndBaseFormat, fmt) { - READWRITE(WithParams(fmt.m_base_format, AsBase<Base>(obj))); + READWRITE(fmt.m_base_format(AsBase<Base>(obj))); if (ser_action.ForRead()) { std::string str; @@ -330,20 +337,20 @@ BOOST_AUTO_TEST_CASE(with_params_base) DataStream stream; - stream << WithParams(BaseFormat::RAW, b); + stream << RAW(b); BOOST_CHECK_EQUAL(stream.str(), "\x0F"); b.m_base_data = 0; - stream >> WithParams(BaseFormat::RAW, b); + stream >> RAW(b); BOOST_CHECK_EQUAL(b.m_base_data, 0x0F); stream.clear(); - stream << WithParams(BaseFormat::HEX, b); + stream << HEX(b); BOOST_CHECK_EQUAL(stream.str(), "0f"); b.m_base_data = 0; - stream >> WithParams(BaseFormat::HEX, b); + stream >> HEX(b); BOOST_CHECK_EQUAL(b.m_base_data, 0x0F); } @@ -353,45 +360,42 @@ BOOST_AUTO_TEST_CASE(with_params_vector_of_base) DataStream stream; - stream << WithParams(BaseFormat::RAW, v); + stream << RAW(v); BOOST_CHECK_EQUAL(stream.str(), "\x02\x0F\xFF"); v[0].m_base_data = 0; v[1].m_base_data = 0; - stream >> WithParams(BaseFormat::RAW, v); + stream >> RAW(v); BOOST_CHECK_EQUAL(v[0].m_base_data, 0x0F); BOOST_CHECK_EQUAL(v[1].m_base_data, 0xFF); stream.clear(); - stream << WithParams(BaseFormat::HEX, v); + stream << HEX(v); BOOST_CHECK_EQUAL(stream.str(), "\x02" "0fff"); v[0].m_base_data = 0; v[1].m_base_data = 0; - stream >> WithParams(BaseFormat::HEX, v); + stream >> HEX(v); BOOST_CHECK_EQUAL(v[0].m_base_data, 0x0F); BOOST_CHECK_EQUAL(v[1].m_base_data, 0xFF); } +constexpr DerivedAndBaseFormat RAW_LOWER{{BaseFormat::RAW}, DerivedAndBaseFormat::DerivedFormat::LOWER}; +constexpr DerivedAndBaseFormat HEX_UPPER{{BaseFormat::HEX}, DerivedAndBaseFormat::DerivedFormat::UPPER}; + BOOST_AUTO_TEST_CASE(with_params_derived) { Derived d; d.m_base_data = 0x0F; d.m_derived_data = "xY"; - DerivedAndBaseFormat fmt; - DataStream stream; - fmt.m_base_format = BaseFormat::RAW; - fmt.m_derived_format = DerivedAndBaseFormat::DerivedFormat::LOWER; - stream << WithParams(fmt, d); + stream << RAW_LOWER(d); - fmt.m_base_format = BaseFormat::HEX; - fmt.m_derived_format = DerivedAndBaseFormat::DerivedFormat::UPPER; - stream << WithParams(fmt, d); + stream << HEX_UPPER(d); BOOST_CHECK_EQUAL(stream.str(), "\x0F\x02xy" "0f\x02XY"); |