diff --git a/nano/core_test/CMakeLists.txt b/nano/core_test/CMakeLists.txt index 0fd4003130..965d128646 100644 --- a/nano/core_test/CMakeLists.txt +++ b/nano/core_test/CMakeLists.txt @@ -33,7 +33,7 @@ add_executable( network.cpp network_filter.cpp node.cpp - object_stream.cpp + object_stream.cpp optimistic_scheduler.cpp processing_queue.cpp processor_service.cpp diff --git a/nano/lib/CMakeLists.txt b/nano/lib/CMakeLists.txt index e290cd765d..b6449e6ed7 100644 --- a/nano/lib/CMakeLists.txt +++ b/nano/lib/CMakeLists.txt @@ -58,9 +58,8 @@ add_library( memory.cpp numbers.hpp numbers.cpp - object_stream.hpp - object_stream_adapters.hpp - object_stream_writers.hpp + object_stream.hpp + object_stream_ostream.hpp observer_set.hpp optional_ptr.hpp processing_queue.hpp diff --git a/nano/lib/object_stream.hpp b/nano/lib/object_stream.hpp index f3b0d7b510..69b9a78e33 100644 --- a/nano/lib/object_stream.hpp +++ b/nano/lib/object_stream.hpp @@ -1,7 +1,5 @@ #pragma once -#include - #include #include @@ -16,6 +14,110 @@ namespace nano { +struct object_stream_config +{ + std::string field_begin{ "" }; + std::string field_end{ "" }; + std::string field_assignment{ ": " }; + std::string field_separator{ ", " }; + + std::string object_begin{ "{ " }; + std::string object_end{ " }" }; + + std::string array_begin{ "[ " }; + std::string array_end{ " ]" }; + + std::string array_element_begin{ "" }; + std::string array_element_end{ "" }; + std::string array_element_separator{ ", " }; + + std::string string_begin{ "\"" }; + std::string string_end{ "\"" }; + + std::string true_value{ "true" }; + std::string false_value{ "false" }; + std::string null_value{ "null" }; + + /** Number of decimal places to show for `float` and `double` */ + int precision{ 2 }; + + static object_stream_config const & default_config () + { + static object_stream_config const config{}; + return config; + } +}; + +struct object_stream_context +{ + object_stream_config const & config; + std::ostream & os; + + explicit object_stream_context (std::ostream & os, object_stream_config const & config = object_stream_config::default_config ()) : + os{ os }, + config{ config } + { + } + + void begin_field (std::string_view name, bool first) + { + if (!first) + { + os << config.field_separator; + } + os << config.field_begin << name << config.field_assignment; + } + + void end_field () + { + os << config.field_end; + } + + void begin_object () + { + os << config.object_begin; + } + + void end_object () + { + os << config.object_end; + } + + void begin_array () + { + os << config.array_begin; + } + + void end_array () + { + os << config.array_end; + } + + void begin_array_element (bool first) + { + if (!first) + { + os << config.array_element_separator; + } + os << config.array_element_begin; + } + + void end_array_element () + { + os << config.array_element_end; + } + + void begin_string () + { + os << config.string_begin; + } + + void end_string () + { + os << config.string_end; + } +}; + class object_stream; class array_stream; @@ -370,4 +472,103 @@ inline void stream_as (Value const & value, array_stream & ars) { value (ars); } +} + +/* + * Specializations for primitive types + */ + +namespace nano +{ +inline void stream_as (bool const & value, object_stream_context & ctx) +{ + ctx.os << (value ? ctx.config.true_value : ctx.config.false_value); +} + +inline void stream_as (const int8_t & value, object_stream_context & ctx) +{ + ctx.os << static_cast (value); // Avoid printing as char +} + +inline void stream_as (const uint8_t & value, object_stream_context & ctx) +{ + ctx.os << static_cast (value); // Avoid printing as char +} + +inline void stream_as (const int16_t & value, object_stream_context & ctx) +{ + ctx.os << value; +} + +inline void stream_as (const uint16_t & value, object_stream_context & ctx) +{ + ctx.os << value; +} + +inline void stream_as (const int32_t & value, object_stream_context & ctx) +{ + ctx.os << value; +} + +inline void stream_as (const uint32_t & value, object_stream_context & ctx) +{ + ctx.os << value; +} + +inline void stream_as (const int64_t & value, object_stream_context & ctx) +{ + ctx.os << value; +} + +inline void stream_as (const uint64_t & value, object_stream_context & ctx) +{ + ctx.os << value; +} + +inline void stream_as (const float & value, object_stream_context & ctx) +{ + ctx.os << std::fixed << std::setprecision (ctx.config.precision) << value; +} + +inline void stream_as (const double & value, object_stream_context & ctx) +{ + ctx.os << std::fixed << std::setprecision (ctx.config.precision) << value; +} + +template +inline void stream_as_optional (const Opt & opt, object_stream_context & ctx) +{ + if (opt) + { + stream_as (*opt, ctx); + } + else + { + ctx.os << ctx.config.null_value; + } +} + +template +inline void stream_as (std::shared_ptr const & value, object_stream_context & ctx) +{ + stream_as_optional (value, ctx); +} + +template +inline void stream_as (std::unique_ptr const & value, object_stream_context & ctx) +{ + stream_as_optional (value, ctx); +} + +template +inline void stream_as (std::weak_ptr const & value, object_stream_context & ctx) +{ + stream_as_optional (value.lock (), ctx); +} + +template +inline void stream_as (std::optional const & value, object_stream_context & ctx) +{ + stream_as_optional (value, ctx); +} } \ No newline at end of file diff --git a/nano/lib/object_stream_adapters.hpp b/nano/lib/object_stream_ostream.hpp similarity index 100% rename from nano/lib/object_stream_adapters.hpp rename to nano/lib/object_stream_ostream.hpp diff --git a/nano/lib/object_stream_writers.hpp b/nano/lib/object_stream_writers.hpp deleted file mode 100644 index 75346a66f1..0000000000 --- a/nano/lib/object_stream_writers.hpp +++ /dev/null @@ -1,203 +0,0 @@ -#pragma once - -#include -#include - -namespace nano -{ -struct object_stream_config -{ - std::string field_begin{ "" }; - std::string field_end{ "" }; - std::string field_assignment{ ": " }; - std::string field_separator{ ", " }; - - std::string object_begin{ "{ " }; - std::string object_end{ " }" }; - - std::string array_begin{ "[ " }; - std::string array_end{ " ]" }; - - std::string array_element_begin{ "" }; - std::string array_element_end{ "" }; - std::string array_element_separator{ ", " }; - - std::string string_begin{ "\"" }; - std::string string_end{ "\"" }; - - std::string true_value{ "true" }; - std::string false_value{ "false" }; - std::string null_value{ "null" }; - - /** Number of decimal places to show for `float` and `double` */ - int precision{ 2 }; - - static object_stream_config const & default_config () - { - static object_stream_config const config{}; - return config; - } -}; - -struct object_stream_context -{ - object_stream_config const & config; - std::ostream & os; - - explicit object_stream_context (std::ostream & os, object_stream_config const & config = object_stream_config::default_config ()) : - os{ os }, - config{ config } - { - } - - void begin_field (std::string_view name, bool first) - { - if (!first) - { - os << config.field_separator; - } - os << config.field_begin << name << config.field_assignment; - } - - void end_field () - { - os << config.field_end; - } - - void begin_object () - { - os << config.object_begin; - } - - void end_object () - { - os << config.object_end; - } - - void begin_array () - { - os << config.array_begin; - } - - void end_array () - { - os << config.array_end; - } - - void begin_array_element (bool first) - { - if (!first) - { - os << config.array_element_separator; - } - os << config.array_element_begin; - } - - void end_array_element () - { - os << config.array_element_end; - } - - void begin_string () - { - os << config.string_begin; - } - - void end_string () - { - os << config.string_end; - } -}; - -inline void stream_as (bool const & value, object_stream_context & ctx) -{ - ctx.os << (value ? ctx.config.true_value : ctx.config.false_value); -} - -inline void stream_as (const int8_t & value, object_stream_context & ctx) -{ - ctx.os << static_cast (value); // Avoid printing as char -} - -inline void stream_as (const uint8_t & value, object_stream_context & ctx) -{ - ctx.os << static_cast (value); // Avoid printing as char -} - -inline void stream_as (const int16_t & value, object_stream_context & ctx) -{ - ctx.os << value; -} - -inline void stream_as (const uint16_t & value, object_stream_context & ctx) -{ - ctx.os << value; -} - -inline void stream_as (const int32_t & value, object_stream_context & ctx) -{ - ctx.os << value; -} - -inline void stream_as (const uint32_t & value, object_stream_context & ctx) -{ - ctx.os << value; -} - -inline void stream_as (const int64_t & value, object_stream_context & ctx) -{ - ctx.os << value; -} - -inline void stream_as (const uint64_t & value, object_stream_context & ctx) -{ - ctx.os << value; -} - -inline void stream_as (const float & value, object_stream_context & ctx) -{ - ctx.os << std::fixed << std::setprecision (ctx.config.precision) << value; -} - -inline void stream_as (const double & value, object_stream_context & ctx) -{ - ctx.os << std::fixed << std::setprecision (ctx.config.precision) << value; -} - -template -inline void stream_as_optional (const Opt & opt, object_stream_context & ctx) -{ - if (opt) - { - stream_as (*opt, ctx); - } - else - { - ctx.os << ctx.config.null_value; - } -} - -template -inline void stream_as (std::shared_ptr const & value, object_stream_context & ctx) -{ - stream_as_optional (value, ctx); -} - -template -inline void stream_as (std::unique_ptr const & value, object_stream_context & ctx) -{ - stream_as_optional (value, ctx); -} - -template -inline void stream_as (std::weak_ptr const & value, object_stream_context & ctx) -{ - stream_as_optional (value.lock (), ctx); -} - -template -inline void stream_as (std::optional const & value, object_stream_context & ctx) -{ - stream_as_optional (value, ctx); -} -} \ No newline at end of file