53    using string_t = 
typename BasicJsonType::string_t;
 
   54    using number_float_t = 
typename BasicJsonType::number_float_t;
 
   55    using number_integer_t = 
typename BasicJsonType::number_integer_t;
 
   56    using number_unsigned_t = 
typename BasicJsonType::number_unsigned_t;
 
   57    using binary_char_t = 
typename BasicJsonType::binary_t::value_type;
 
   58    static constexpr std::uint8_t UTF8_ACCEPT = 0;
 
   59    static constexpr std::uint8_t UTF8_REJECT = 1;
 
   69               size_t indent_init_len = 512)
 
   71        , loc(
std::localeconv())
 
   72        , thousands_sep(loc->thousands_sep == nullptr ? 
'\0' : 
std::
char_traits<char>::to_char_type(* (loc->thousands_sep)))
 
   73        , decimal_point(loc->decimal_point == nullptr ? 
'\0' : 
std::
char_traits<char>::to_char_type(* (loc->decimal_point)))
 
   75        , indent_string(indent_init_len, indent_char)
 
   76        , error_handler(error_handler_)
 
 
   80               size_t indent_init_len = 512,
 
 
  114    void dump(
const BasicJsonType& val,
 
  115              const bool pretty_print,
 
  116              const bool ensure_ascii,
 
  117              const unsigned int indent_step,
 
  118              const unsigned int current_indent = 0)
 
  120        switch (val.m_data.m_type)
 
  124                if (val.m_data.m_value.object->empty())
 
  126                    o->write_characters(
"{}", 2);
 
  132                    o->write_characters(
"{\n", 2);
 
  135                    const auto new_indent = current_indent + indent_step;
 
  138                        indent_string.resize(indent_string.size() * 2, 
' ');
 
  142                    auto i = val.m_data.m_value.object->cbegin();
 
  143                    for (std::size_t cnt = 0; cnt < val.m_data.m_value.object->size() - 1; ++cnt, ++i)
 
  145                        o->write_characters(indent_string.c_str(), new_indent);
 
  146                        o->write_character(
'\"');
 
  148                        o->write_characters(
"\": ", 3);
 
  149                        dump(i->second, 
true, ensure_ascii, indent_step, new_indent);
 
  150                        o->write_characters(
",\n", 2);
 
  154                    JSON_ASSERT(i != val.m_data.m_value.object->cend());
 
  155                    JSON_ASSERT(std::next(i) == val.m_data.m_value.object->cend());
 
  156                    o->write_characters(indent_string.c_str(), new_indent);
 
  157                    o->write_character(
'\"');
 
  159                    o->write_characters(
"\": ", 3);
 
  160                    dump(i->second, 
true, ensure_ascii, indent_step, new_indent);
 
  162                    o->write_character(
'\n');
 
  163                    o->write_characters(indent_string.c_str(), current_indent);
 
  164                    o->write_character(
'}');
 
  168                    o->write_character(
'{');
 
  171                    auto i = val.m_data.m_value.object->cbegin();
 
  172                    for (std::size_t cnt = 0; cnt < val.m_data.m_value.object->size() - 1; ++cnt, ++i)
 
  174                        o->write_character(
'\"');
 
  176                        o->write_characters(
"\":", 2);
 
  177                        dump(i->second, 
false, ensure_ascii, indent_step, current_indent);
 
  178                        o->write_character(
',');
 
  182                    JSON_ASSERT(i != val.m_data.m_value.object->cend());
 
  183                    JSON_ASSERT(std::next(i) == val.m_data.m_value.object->cend());
 
  184                    o->write_character(
'\"');
 
  186                    o->write_characters(
"\":", 2);
 
  187                    dump(i->second, 
false, ensure_ascii, indent_step, current_indent);
 
  189                    o->write_character(
'}');
 
  197                if (val.m_data.m_value.array->empty())
 
  199                    o->write_characters(
"[]", 2);
 
  205                    o->write_characters(
"[\n", 2);
 
  208                    const auto new_indent = current_indent + indent_step;
 
  211                        indent_string.resize(indent_string.size() * 2, 
' ');
 
  215                    for (
auto i = val.m_data.m_value.array->cbegin();
 
  216                            i != val.m_data.m_value.array->cend() - 1; ++i)
 
  218                        o->write_characters(indent_string.c_str(), new_indent);
 
  219                        dump(*i, 
true, ensure_ascii, indent_step, new_indent);
 
  220                        o->write_characters(
",\n", 2);
 
  225                    o->write_characters(indent_string.c_str(), new_indent);
 
  226                    dump(val.m_data.m_value.array->back(), 
true, ensure_ascii, indent_step, new_indent);
 
  228                    o->write_character(
'\n');
 
  229                    o->write_characters(indent_string.c_str(), current_indent);
 
  230                    o->write_character(
']');
 
  234                    o->write_character(
'[');
 
  237                    for (
auto i = val.m_data.m_value.array->cbegin();
 
  238                            i != val.m_data.m_value.array->cend() - 1; ++i)
 
  240                        dump(*i, 
false, ensure_ascii, indent_step, current_indent);
 
  241                        o->write_character(
',');
 
  246                    dump(val.m_data.m_value.array->back(), 
false, ensure_ascii, indent_step, current_indent);
 
  248                    o->write_character(
']');
 
  256                o->write_character(
'\"');
 
  258                o->write_character(
'\"');
 
  266                    o->write_characters(
"{\n", 2);
 
  269                    const auto new_indent = current_indent + indent_step;
 
  272                        indent_string.resize(indent_string.size() * 2, 
' ');
 
  275                    o->write_characters(indent_string.c_str(), new_indent);
 
  277                    o->write_characters(
"\"bytes\": [", 10);
 
  279                    if (!val.m_data.m_value.binary->empty())
 
  281                        for (
auto i = val.m_data.m_value.binary->cbegin();
 
  282                                i != val.m_data.m_value.binary->cend() - 1; ++i)
 
  285                            o->write_characters(
", ", 2);
 
  290                    o->write_characters(
"],\n", 3);
 
  291                    o->write_characters(indent_string.c_str(), new_indent);
 
  293                    o->write_characters(
"\"subtype\": ", 11);
 
  294                    if (val.m_data.m_value.binary->has_subtype())
 
  300                        o->write_characters(
"null", 4);
 
  302                    o->write_character(
'\n');
 
  303                    o->write_characters(indent_string.c_str(), current_indent);
 
  304                    o->write_character(
'}');
 
  308                    o->write_characters(
"{\"bytes\":[", 10);
 
  310                    if (!val.m_data.m_value.binary->empty())
 
  312                        for (
auto i = val.m_data.m_value.binary->cbegin();
 
  313                                i != val.m_data.m_value.binary->cend() - 1; ++i)
 
  316                            o->write_character(
',');
 
  321                    o->write_characters(
"],\"subtype\":", 12);
 
  322                    if (val.m_data.m_value.binary->has_subtype())
 
  325                        o->write_character(
'}');
 
  329                        o->write_characters(
"null}", 5);
 
  337                if (val.m_data.m_value.boolean)
 
  339                    o->write_characters(
"true", 4);
 
  343                    o->write_characters(
"false", 5);
 
  368                o->write_characters(
"<discarded>", 11);
 
  374                o->write_characters(
"null", 4);
 
 
  400        std::uint32_t codepoint{};
 
  401        std::uint8_t 
state = UTF8_ACCEPT;
 
  402        std::size_t 
bytes = 0;  
 
  405        std::size_t bytes_after_last_accept = 0;
 
  406        std::size_t undumped_chars = 0;
 
  408        for (std::size_t i = 0; i < s.size(); ++i)
 
  410            const auto byte = 
static_cast<std::uint8_t
>(s[i]);
 
  412            switch (decode(
state, codepoint, 
byte))
 
  471                            if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
 
  473                                if (codepoint <= 0xFFFF)
 
  477                                                                      static_cast<std::uint16_t
>(codepoint)));
 
  484                                                                      static_cast<std::uint16_t
>(0xD7C0u + (codepoint >> 10u)),
 
  485                                                                      static_cast<std::uint16_t
>(0xDC00u + (codepoint & 0x3FFu))));
 
  509                    bytes_after_last_accept = 
bytes;
 
  516                    switch (error_handler)
 
  530                            if (undumped_chars > 0)
 
  537                            bytes = bytes_after_last_accept;
 
  567                                bytes_after_last_accept = 
bytes;
 
  608            switch (error_handler)
 
  618                    o->write_characters(
string_buffer.data(), bytes_after_last_accept);
 
  625                    o->write_characters(
string_buffer.data(), bytes_after_last_accept);
 
  629                        o->write_characters(
"\\ufffd", 6);
 
  633                        o->write_characters(
"\xEF\xBF\xBD", 3);
 
 
  653    inline unsigned int count_digits(number_unsigned_t x) 
noexcept 
  655        unsigned int n_digits = 1;
 
  684    static std::string hex_bytes(std::uint8_t 
byte)
 
  686        std::string result = 
"FF";
 
  687        constexpr const char* nibble_to_hex = 
"0123456789ABCDEF";
 
  688        result[0] = nibble_to_hex[
byte / 16];
 
  689        result[1] = nibble_to_hex[
byte % 16];
 
  694    template <typename NumberType, enable_if_t<std::is_signed<NumberType>::value, 
int> = 0>
 
  695    bool is_negative_number(NumberType x)
 
  700    template < typename NumberType, enable_if_t <std::is_unsigned<NumberType>::value, 
int > = 0 >
 
  701    bool is_negative_number(NumberType )
 
  717                   std::is_integral<NumberType>::value ||
 
  718                   std::is_same<NumberType, number_unsigned_t>::value ||
 
  719                   std::is_same<NumberType, number_integer_t>::value ||
 
  720                   std::is_same<NumberType, binary_char_t>::value,
 
  724        static constexpr std::array<std::array<char, 2>, 100> digits_to_99
 
  727                {{
'0', 
'0'}}, {{
'0', 
'1'}}, {{
'0', 
'2'}}, {{
'0', 
'3'}}, {{
'0', 
'4'}}, {{
'0', 
'5'}}, {{
'0', 
'6'}}, {{
'0', 
'7'}}, {{
'0', 
'8'}}, {{
'0', 
'9'}},
 
  728                {{
'1', 
'0'}}, {{
'1', 
'1'}}, {{
'1', 
'2'}}, {{
'1', 
'3'}}, {{
'1', 
'4'}}, {{
'1', 
'5'}}, {{
'1', 
'6'}}, {{
'1', 
'7'}}, {{
'1', 
'8'}}, {{
'1', 
'9'}},
 
  729                {{
'2', 
'0'}}, {{
'2', 
'1'}}, {{
'2', 
'2'}}, {{
'2', 
'3'}}, {{
'2', 
'4'}}, {{
'2', 
'5'}}, {{
'2', 
'6'}}, {{
'2', 
'7'}}, {{
'2', 
'8'}}, {{
'2', 
'9'}},
 
  730                {{
'3', 
'0'}}, {{
'3', 
'1'}}, {{
'3', 
'2'}}, {{
'3', 
'3'}}, {{
'3', 
'4'}}, {{
'3', 
'5'}}, {{
'3', 
'6'}}, {{
'3', 
'7'}}, {{
'3', 
'8'}}, {{
'3', 
'9'}},
 
  731                {{
'4', 
'0'}}, {{
'4', 
'1'}}, {{
'4', 
'2'}}, {{
'4', 
'3'}}, {{
'4', 
'4'}}, {{
'4', 
'5'}}, {{
'4', 
'6'}}, {{
'4', 
'7'}}, {{
'4', 
'8'}}, {{
'4', 
'9'}},
 
  732                {{
'5', 
'0'}}, {{
'5', 
'1'}}, {{
'5', 
'2'}}, {{
'5', 
'3'}}, {{
'5', 
'4'}}, {{
'5', 
'5'}}, {{
'5', 
'6'}}, {{
'5', 
'7'}}, {{
'5', 
'8'}}, {{
'5', 
'9'}},
 
  733                {{
'6', 
'0'}}, {{
'6', 
'1'}}, {{
'6', 
'2'}}, {{
'6', 
'3'}}, {{
'6', 
'4'}}, {{
'6', 
'5'}}, {{
'6', 
'6'}}, {{
'6', 
'7'}}, {{
'6', 
'8'}}, {{
'6', 
'9'}},
 
  734                {{
'7', 
'0'}}, {{
'7', 
'1'}}, {{
'7', 
'2'}}, {{
'7', 
'3'}}, {{
'7', 
'4'}}, {{
'7', 
'5'}}, {{
'7', 
'6'}}, {{
'7', 
'7'}}, {{
'7', 
'8'}}, {{
'7', 
'9'}},
 
  735                {{
'8', 
'0'}}, {{
'8', 
'1'}}, {{
'8', 
'2'}}, {{
'8', 
'3'}}, {{
'8', 
'4'}}, {{
'8', 
'5'}}, {{
'8', 
'6'}}, {{
'8', 
'7'}}, {{
'8', 
'8'}}, {{
'8', 
'9'}},
 
  736                {{
'9', 
'0'}}, {{
'9', 
'1'}}, {{
'9', 
'2'}}, {{
'9', 
'3'}}, {{
'9', 
'4'}}, {{
'9', 
'5'}}, {{
'9', 
'6'}}, {{
'9', 
'7'}}, {{
'9', 
'8'}}, {{
'9', 
'9'}},
 
  743            o->write_character(
'0');
 
  748        auto buffer_ptr = number_buffer.begin(); 
 
  750        number_unsigned_t abs_value;
 
  752        unsigned int n_chars{};
 
  754        if (is_negative_number(x))
 
  757            abs_value = remove_sign(
static_cast<number_integer_t
>(x));
 
  760            n_chars = 1 + count_digits(abs_value);
 
  764            abs_value = 
static_cast<number_unsigned_t
>(x);
 
  765            n_chars = count_digits(abs_value);
 
  773        buffer_ptr += n_chars;
 
  777        while (abs_value >= 100)
 
  779            const auto digits_index = 
static_cast<unsigned>((abs_value % 100));
 
  781            *(--buffer_ptr) = digits_to_99[digits_index][1];
 
  782            *(--buffer_ptr) = digits_to_99[digits_index][0];
 
  787            const auto digits_index = 
static_cast<unsigned>(abs_value);
 
  788            *(--buffer_ptr) = digits_to_99[digits_index][1];
 
  789            *(--buffer_ptr) = digits_to_99[digits_index][0];
 
  793            *(--buffer_ptr) = 
static_cast<char>(
'0' + abs_value);
 
  796        o->write_characters(number_buffer.data(), n_chars);
 
 
  810        if (!std::isfinite(x))
 
  812            o->write_characters(
"null", 4);
 
  821        static constexpr bool is_ieee_single_or_double
 
  822            = (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 24 && std::numeric_limits<number_float_t>::max_exponent == 128) ||
 
  823              (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 53 && std::numeric_limits<number_float_t>::max_exponent == 1024);
 
  825        dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
 
 
  830        auto* begin = number_buffer.data();
 
  831        auto* end = ::wpi::detail::to_chars(begin, begin + number_buffer.size(), x);
 
  833        o->write_characters(begin, 
static_cast<size_t>(end - begin));
 
 
  839        static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
 
  843        std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), 
"%.*g", d, x);
 
  848        JSON_ASSERT(
static_cast<std::size_t
>(len) < number_buffer.size());
 
  851        if (thousands_sep != 
'\0')
 
  854            const auto end = std::remove(number_buffer.begin(), number_buffer.begin() + len, thousands_sep);
 
  855            std::fill(end, number_buffer.end(), 
'\0');
 
  857            len = (end - number_buffer.begin());
 
  861        if (decimal_point != 
'\0' && decimal_point != 
'.')
 
  864            const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
 
  865            if (dec_pos != number_buffer.end())
 
  871        o->write_characters(number_buffer.data(), 
static_cast<std::size_t
>(len));
 
  874        const bool value_is_int_like =
 
  875            std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
 
  878            return c == 
'.' || c == 
'e';
 
  881        if (value_is_int_like)
 
  883            o->write_characters(
".0", 2);
 
 
  909    static std::uint8_t decode(std::uint8_t& 
state, std::uint32_t& codep, 
const std::uint8_t 
byte) 
noexcept 
  911        static const std::array<std::uint8_t, 400> utf8d =
 
  914                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
 
  915                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
 
  916                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
 
  917                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
 
  918                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 
 
  919                7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
 
  920                8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
 
  921                0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, 
 
  922                0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 
 
  923                0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, 
 
  924                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 
 
  925                1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 
 
  926                1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 
 
  927                1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 
 
  932        const std::uint8_t type = utf8d[byte];
 
  934        codep = (
state != UTF8_ACCEPT)
 
  935                ? (
byte & 0x3fu) | (codep << 6u)
 
  936                : (0xFFu >> type) & (byte);
 
  938        const std::size_t 
index = 256u + 
static_cast<size_t>(
state) * 16u + 
static_cast<size_t>(
type);
 
  949    number_unsigned_t remove_sign(number_unsigned_t x)
 
  964    inline number_unsigned_t remove_sign(number_integer_t x) 
noexcept 
  966        JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)()); 
 
  967        return static_cast<number_unsigned_t
>(-(x + 1)) + 1;
 
  975    std::array<char, 64> number_buffer{{}};
 
  978    const std::lconv* loc = 
nullptr;
 
  980    const char thousands_sep = 
'\0';
 
  982    const char decimal_point = 
'\0';
 
  988    const char indent_char;
 
  990    string_t indent_string;