From ec0f7443308992bc8822e6774352d0e5f4edefef Mon Sep 17 00:00:00 2001 From: MistEO Date: Sat, 21 Oct 2023 04:06:57 +0800 Subject: [PATCH] feat: support custom string_converter for json::serialize --- include/json.hpp | 60 ++++++++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 27 deletions(-) diff --git a/include/json.hpp b/include/json.hpp index a3e3505..fa6d4d8 100644 --- a/include/json.hpp +++ b/include/json.hpp @@ -565,8 +565,14 @@ namespace literals template const basic_value invalid_value(); -template -basic_value serialize(any_t&& arg); +namespace _serialization_helper +{ + template + struct string_converter; +} +template > +basic_value serialize(any_t&& arg, string_converter_t&& string_converter = {}); // ****************************** // * basic_value impl * @@ -2565,39 +2571,39 @@ namespace _serialization_helper template constexpr bool is_sequence_container = is_container && !is_associative_container; - template - MEOJSON_INLINE string_t to_stream_string(input_t&& arg) + template + struct string_converter { using char_t = typename string_t::value_type; using ostringstream_t = std::basic_ostringstream, std::allocator>; - ostringstream_t os; - os << std::forward(arg); - return std::move(os).str(); - } + static constexpr bool stream = loose; - template - MEOJSON_INLINE string_t to_string(input_t&& arg) - { - if constexpr (std::is_constructible_v) { - return arg; - } - else if constexpr (loose) { - return to_stream_string(std::forward(arg)); - } - else { - static_assert(!sizeof(input_t), "Unable to convert type to string."); + template + string_t operator()(input_t&& arg) const + { + if constexpr (std::is_constructible_v) { + return string_t(std::forward(arg)); + } + else if constexpr (stream && has_output_operator::value) { + ostringstream_t os; + os << std::forward(arg); + return std::move(os).str(); + } + else { + static_assert(!sizeof(input_t), "Unable to convert type to string."); + } } - } + }; } -template -MEOJSON_INLINE basic_value serialize(any_t&& arg) +template +MEOJSON_INLINE basic_value serialize(any_t&& arg, string_converter_t&& string_converter) { using namespace _serialization_helper; if constexpr (std::is_constructible_v, any_t>) { - return arg; + return basic_value(std::forward(arg)); } else if constexpr (std::is_constructible_v, any_t>) { return basic_array(std::forward(arg)); @@ -2610,7 +2616,7 @@ MEOJSON_INLINE basic_value serialize(any_t&& arg) for (auto&& val : arg) { using value_t = decltype(val); - result.emplace(serialize(std::forward(val))); + result.emplace(serialize(std::forward(val), string_converter)); } return result; } @@ -2620,13 +2626,13 @@ MEOJSON_INLINE basic_value serialize(any_t&& arg) using key_t = decltype(key); using value_t = decltype(val); - result.emplace(to_string(std::forward(key)), - serialize(std::forward(val))); + result.emplace(string_converter(std::forward(key)), + serialize(std::forward(val), string_converter)); } return result; } else { - return to_string(std::forward(arg)); + return string_converter(std::forward(arg)); } }