Skip to content

Commit

Permalink
feat: support custom streamer for serialize
Browse files Browse the repository at this point in the history
  • Loading branch information
MistEO committed Oct 20, 2023
1 parent b75252f commit ae7d044
Showing 1 changed file with 20 additions and 18 deletions.
38 changes: 20 additions & 18 deletions include/json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -565,9 +565,6 @@ namespace literals
template <typename string_t = default_string_t>
const basic_value<string_t> invalid_value();

template <bool stream, typename any_t, typename string_t = default_string_t>
basic_value<string_t> serialize(any_t&& arg);

// ******************************
// * basic_value impl *
// ******************************
Expand Down Expand Up @@ -2565,34 +2562,39 @@ namespace _serialization_helper
template <typename T>
constexpr bool is_sequence_container<T> = is_container<T> && !is_associative_container<T>;

template <typename input_t, typename string_t>
MEOJSON_INLINE string_t to_stream_string(input_t&& arg)
template <typename string_t>
struct string_streamer
{
using char_t = typename string_t::value_type;
using ostringstream_t = std::basic_ostringstream<char_t, std::char_traits<char_t>, std::allocator<char_t>>;

ostringstream_t os;
os << std::forward<input_t>(arg);
return std::move(os).str();
}
template <typename input_t>
string_t operator()(input_t&& arg) const
{
ostringstream_t os;
os << std::forward<input_t>(arg);
return std::move(os).str();
}
};

template <bool stream, typename input_t, typename string_t>
MEOJSON_INLINE string_t to_string(input_t&& arg)
template <bool stream, typename input_t, typename string_t, typename streamer_t>
MEOJSON_INLINE string_t to_string(input_t&& arg, streamer_t&& streamer)
{
if constexpr (std::is_constructible_v<string_t, input_t>) {
return arg;
}
else if constexpr (stream) {
return to_stream_string<input_t, string_t>(std::forward<input_t>(arg));
return streamer(std::forward<input_t>(arg));
}
else {
static_assert(!sizeof(input_t), "Unable to convert type to string.");
}
}
}

template <bool stream, typename any_t, typename string_t>
MEOJSON_INLINE basic_value<string_t> serialize(any_t&& arg)
template <bool stream, typename any_t, typename string_t = default_string_t,
typename streamer_t = _serialization_helper::string_streamer<string_t>>
MEOJSON_INLINE basic_value<string_t> serialize(any_t&& arg, streamer_t&& streamer = streamer_t())
{
using namespace _serialization_helper;

Expand All @@ -2610,7 +2612,7 @@ MEOJSON_INLINE basic_value<string_t> serialize(any_t&& arg)
for (auto&& val : arg) {
using value_t = decltype(val);

result.emplace(serialize<stream, value_t, string_t>(std::forward<value_t>(val)));
result.emplace(serialize<stream, value_t, string_t>(std::forward<value_t>(val), streamer));
}
return result;
}
Expand All @@ -2620,13 +2622,13 @@ MEOJSON_INLINE basic_value<string_t> serialize(any_t&& arg)
using key_t = decltype(key);
using value_t = decltype(val);

result.emplace(to_string<stream, key_t, string_t>(std::forward<key_t>(key)),
serialize<stream, value_t, string_t>(std::forward<value_t>(val)));
result.emplace(to_string<stream, key_t, string_t>(std::forward<key_t>(key), streamer),
serialize<stream, value_t, string_t>(std::forward<value_t>(val), streamer));
}
return result;
}
else {
return to_string<stream, any_t, string_t>(std::forward<any_t>(arg));
return to_string<stream, any_t, string_t>(std::forward<any_t>(arg), streamer);
}
}

Expand Down

0 comments on commit ae7d044

Please sign in to comment.