diff --git a/nano/lib/object_stream.hpp b/nano/lib/object_stream.hpp index b4ee0c87a3..f3b0d7b510 100644 --- a/nano/lib/object_stream.hpp +++ b/nano/lib/object_stream.hpp @@ -75,32 +75,36 @@ class object_stream : private object_stream_base ctx.end_field (); } - // Handle `.write ("name", container, [] (auto const & entry) { ... })` + // Handle `.write_range ("name", container)` + template + inline void write_range (std::string_view name, Container const & container); + + // Handle `.write_range ("name", container, [] (auto const & entry) { ... })` template requires (std::is_invocable_v) - void write (std::string_view name, Container const & container, Transform transform) + void write_range (std::string_view name, Container const & container, Transform transform) { - write (name, std::views::transform (container, transform)); + write_range (name, std::views::transform (container, transform)); } - // Handle `.write ("name", container, [] (auto const & entry, nano::object_stream & obs) { ... })` + // Handle `.write_range ("name", container, [] (auto const & entry, nano::object_stream &) { ... })` template requires (std::is_invocable_v) - void write (std::string_view name, Container const & container, Writer writer) + void write_range (std::string_view name, Container const & container, Writer writer) { - write (name, container, [&writer] (auto const & el) { + write_range (name, container, [&writer] (auto const & el) { return [&writer, &el] (object_stream & obs) { writer (el, obs); }; }); } - // Handle `.write ("name", container, [] (auto const & entry, nano::array_stream & obs) { ... })` + // Handle `.write_range ("name", container, [] (auto const & entry, nano::array_stream &) { ... })` template requires (std::is_invocable_v) - void write (std::string_view name, Container const & container, Writer writer) + void write_range (std::string_view name, Container const & container, Writer writer) { - write (name, container, [&writer] (auto const & el) { + write_range (name, container, [&writer] (auto const & el) { return [&writer, &el] (array_stream & obs) { writer (el, obs); }; @@ -132,32 +136,36 @@ class array_stream : private object_stream_base ctx.end_array_element (); } - // Handle `.write (container, [] (auto const & entry) { ... })` + // Handle `.write_range (container)` + template + inline void write_range (Container const & container); + + // Handle `.write_range (container, [] (auto const & entry) { ... })` template requires (std::is_invocable_v) - void write (Container const & container, Transform transform) + void write_range (Container const & container, Transform transform) { - write (std::views::transform (container, transform)); + write_range (std::views::transform (container, transform)); } - // Handle `.write (container, [] (auto const & entry, nano::object_stream & obs) { ... })` + // Handle `.write_range (container, [] (auto const & entry, nano::object_stream &) { ... })` template requires (std::is_invocable_v) - void write (Container const & container, Writer writer) + void write_range (Container const & container, Writer writer) { - write (container, [&writer] (auto const & el) { + write_range (container, [&writer] (auto const & el) { return [&writer, &el] (object_stream & obs) { writer (el, obs); }; }); } - // Handle `.write (container, [] (auto const & entry, nano::array_stream & obs) { ... })` + // Handle `.write_range (container, [] (auto const & entry, nano::array_stream &) { ... })` template requires (std::is_invocable_v) - void write (Container const & container, Writer writer) + void write_range (Container const & container, Writer writer) { - write (container, [&writer] (auto const & el) { + write_range (container, [&writer] (auto const & el) { return [&writer, &el] (array_stream & obs) { writer (el, obs); }; @@ -187,32 +195,36 @@ class root_object_stream : private object_stream_base stream_as (value, ctx); } - // Handle `.write (container, [] (auto const & entry) { ... })` + // Handle `.write_range (container)` + template + inline void write_range (Container const & container); + + // Handle `.write_range (container, [] (auto const & entry) { ... })` template requires (std::is_invocable_v) - void write (Container const & container, Transform transform) + void write_range (Container const & container, Transform transform) { - write (std::views::transform (container, transform)); + write_range (std::views::transform (container, transform)); } - // Handle `.write (container, [] (auto const & entry, nano::object_stream & obs) { ... })` + // Handle `.write_range (container, [] (auto const & entry, nano::object_stream &) { ... })` template requires (std::is_invocable_v) - void write (Container const & container, Writer writer) + void write_range (Container const & container, Writer writer) { - write (container, [&writer] (auto const & el) { + write_range (container, [&writer] (auto const & el) { return [&writer, &el] (object_stream & obs) { writer (el, obs); }; }); } - // Handle `.write (container, [] (auto const & entry, nano::array_stream & obs) { ... })` + // Handle `.write_range (container, [] (auto const & entry, nano::array_stream &) { ... })` template requires (std::is_invocable_v) - void write (Container const & container, Writer writer) + void write_range (Container const & container, Writer writer) { - write (container, [&writer] (auto const & el) { + write_range (container, [&writer] (auto const & el) { return [&writer, &el] (array_stream & obs) { writer (el, obs); }; @@ -220,6 +232,43 @@ class root_object_stream : private object_stream_base } }; +/* + * Implementation for `write_range` functions + */ + +template +inline void nano::object_stream::write_range (std::string_view name, Container const & container) +{ + write (name, [&container] (array_stream & ars) { + for (auto const & el : container) + { + ars.write (el); + } + }); +} + +template +inline void nano::array_stream::write_range (Container const & container) +{ + write ([&container] (array_stream & ars) { + for (auto const & el : container) + { + ars.write (el); + } + }); +} + +template +inline void nano::root_object_stream::write_range (Container const & container) +{ + write ([&container] (array_stream & ars) { + for (auto const & el : container) + { + ars.write (el); + } + }); +} + /** * Wraps {name,value} args and provides a `<< (std::ostream &, ...)` operator that writes the arguments to the stream in a lazy manner. */ @@ -321,17 +370,4 @@ inline void stream_as (Value const & value, array_stream & ars) { value (ars); } - -/* - * Make ranges automatically streamable as arrays - */ - -template -inline void stream_as (Range const & range, array_stream & ars) -{ - for (auto const & el : range) - { - ars.write (el); - } -} } \ No newline at end of file diff --git a/nano/lib/object_stream_writers.hpp b/nano/lib/object_stream_writers.hpp index 002cfebbee..75346a66f1 100644 --- a/nano/lib/object_stream_writers.hpp +++ b/nano/lib/object_stream_writers.hpp @@ -200,27 +200,4 @@ inline void stream_as (std::optional const & value, object_stream_context { stream_as_optional (value, ctx); } - -template -inline void stream_as_string (const Str & str, object_stream_context & ctx) -{ - ctx.begin_string (); - ctx.os << str; - ctx.end_string (); -} - -inline void stream_as (std::string const & value, object_stream_context & ctx) -{ - stream_as_string (value, ctx); -} - -inline void stream_as (std::string_view const & value, object_stream_context & ctx) -{ - stream_as_string (value, ctx); -} - -inline void stream_as (const char * value, object_stream_context & ctx) -{ - stream_as_string (value, ctx); -} } \ No newline at end of file diff --git a/nano/node/election.cpp b/nano/node/election.cpp index 4d57ea2643..fea4f8b503 100644 --- a/nano/node/election.cpp +++ b/nano/node/election.cpp @@ -761,12 +761,12 @@ void nano::election::operator() (nano::object_stream & obs) const obs.write ("tally_amount", status.tally.to_string_dec ()); obs.write ("final_tally_amount", status.final_tally.to_string_dec ()); - obs.write ("blocks", last_blocks, [] (auto const & entry) { + obs.write_range ("blocks", last_blocks, [] (auto const & entry) { auto [hash, block] = entry; return block; }); - obs.write ("votes", last_votes, [] (auto const & entry, nano::object_stream & obs) { + obs.write_range ("votes", last_votes, [] (auto const & entry, nano::object_stream & obs) { auto & [account, info] = entry; obs.write ("account", account.to_account ()); obs.write ("time", info.time.time_since_epoch ().count ()); @@ -776,7 +776,7 @@ void nano::election::operator() (nano::object_stream & obs) const auto tally = tally_impl (); - obs.write ("tally", tally, [] (auto const & entry, nano::object_stream & obs) { + obs.write_range ("tally", tally, [] (auto const & entry, nano::object_stream & obs) { auto & [amount, block] = entry; obs.write ("amount", amount); obs.write ("hash", block->hash ().to_string ()); diff --git a/nano/node/messages.cpp b/nano/node/messages.cpp index 37479bc4ac..bd253b917e 100644 --- a/nano/node/messages.cpp +++ b/nano/node/messages.cpp @@ -416,7 +416,7 @@ void nano::keepalive::operator() (nano::object_stream & obs) const { nano::message::operator() (obs); // Write common data - obs.write ("peers", peers); + obs.write_range ("peers", peers); } /* @@ -595,7 +595,7 @@ void nano::confirm_req::operator() (nano::object_stream & obs) const nano::message::operator() (obs); // Write common data // Write roots as: [ { root: ##, hash: ## } ,...] - obs.write ("roots", roots_hashes, [] (auto const & root_hash, nano::object_stream & obs) { + obs.write_range ("roots", roots_hashes, [] (auto const & root_hash, nano::object_stream & obs) { auto [root, hash] = root_hash; obs.write ("root", root); obs.write ("hash", hash); @@ -1882,7 +1882,7 @@ void nano::asc_pull_ack::blocks_payload::deserialize (nano::stream & stream) void nano::asc_pull_ack::blocks_payload::operator() (nano::object_stream & obs) const { - obs.write ("blocks", blocks); + obs.write_range ("blocks", blocks); } /* @@ -1962,7 +1962,7 @@ void nano::asc_pull_ack::frontiers_payload::deserialize (nano::stream & stream) void nano::asc_pull_ack::frontiers_payload::operator() (nano::object_stream & obs) const { - obs.write ("frontiers", frontiers, [] (auto const & entry, nano::object_stream & obs) { + obs.write_range ("frontiers", frontiers, [] (auto const & entry, nano::object_stream & obs) { auto & [account, hash] = entry; obs.write ("account", account); obs.write ("hash", hash); diff --git a/nano/secure/vote.cpp b/nano/secure/vote.cpp index f4607e5258..3949e304f0 100644 --- a/nano/secure/vote.cpp +++ b/nano/secure/vote.cpp @@ -186,5 +186,5 @@ void nano::vote::operator() (nano::object_stream & obs) const { obs.write ("account", account); obs.write ("timestamp", timestamp_m); - obs.write ("hashes", hashes); + obs.write_range ("hashes", hashes); } \ No newline at end of file