3#include <md/object.hpp>
12#include <system_error>
19inline void write_json_string(std::ostream& os,
const std::string_view s) {
21 for (
const char c : s) {
45 if (
static_cast<unsigned char>(c) < 0x20) {
46 static constexpr std::array<char, 16> hex = {
47 '0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'a',
'b',
'c',
'd',
'e',
'f'};
49 os.put(hex[(
static_cast<unsigned char>(c) >> 4U) & 0xFU]);
50 os.put(hex[
static_cast<unsigned char>(c) & 0xFU]);
63inline void write_json_floating(std::ostream& os,
const T v) {
64 static_assert(std::is_floating_point_v<T>);
65 std::array<char, 64> buf{};
66 auto [end, ec] = std::to_chars(buf.data(), buf.data() + buf.size(), v);
68 os.write(buf.data(), end - buf.data());
71void write_json(std::ostream& os,
const Value& v);
73inline void write_json(std::ostream& os,
const Array& a) {
76 for (
const auto& el : a) {
86inline void write_json(std::ostream& os,
const Object& o) {
89 for (
const auto& [k, val] : o) {
94 write_json_string(os, k);
101inline void write_json(std::ostream& os,
const Value& v) {
104 using T = std::decay_t<
decltype(x)>;
105 if constexpr (std::is_same_v<T, std::nullptr_t>) {
107 }
else if constexpr (std::is_same_v<T, bool>) {
108 os << (x ?
"true" :
"false");
109 }
else if constexpr (std::is_same_v<T, std::int64_t> ||
110 std::is_same_v<T, std::uint64_t>) {
112 }
else if constexpr (std::is_same_v<T, float> || std::is_same_v<T, double>) {
113 write_json_floating(os, x);
114 }
else if constexpr (std::is_same_v<T, std::string>) {
115 write_json_string(os, x);
116 }
else if constexpr (std::is_same_v<T, Array>) {
118 }
else if constexpr (std::is_same_v<T, std::unique_ptr<Object>>) {
128inline std::ostream& operator<<(std::ostream& os,
const Value& v) {
129 detail::write_json(os, v);
133inline std::ostream& operator<<(std::ostream& os,
const Object& o) {
134 detail::write_json(os, o);
138inline std::ostream& operator<<(std::ostream& os,
const Array& a) {
139 detail::write_json(os, a);