Coverage Report

Created: 2026-10-28 06:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/glaze/include/glaze/json/minify.hpp
Line
Count
Source
1
// Glaze Library
2
// For the license information refer to glaze.hpp
3
4
#pragma once
5
6
// Minifying JSONC handles both comment styles. A block comment is carried through as written; a
7
// line comment is dropped, because minifying is what removes the newline that ends it and without
8
// that newline the comment would swallow everything written after it.
9
10
#include "glaze/json/json_format.hpp"
11
12
namespace glz
13
{
14
   namespace detail
15
   {
16
      template <auto Opts>
17
      inline void minify_json(is_context auto&& ctx, auto&& it, auto&& end, auto&& b, auto& ix) noexcept
18
26.4k
      {
19
26.4k
         using enum json_type;
20
21
         // Every write below goes through this, and the dump it makes is unchecked: the caller's
22
         // one-shot sizing covers a resizable destination, because minifying only ever removes
23
         // bytes, so the input's length is room enough.
24
         //
25
         // A bounded destination cannot be grown, and asking it for the input's length up front
26
         // refuses a buffer that fits the result -- sizing the output to the minified length is the
27
         // obvious thing to do, and `{ "a" : 1 }` into a 7 byte buffer has to work. So each write
28
         // asks for exactly what it stores instead; see emit_bytes for where that count comes from.
29
         // None of it survives for a resizable destination, which keeps the unchecked dumps and
30
         // nothing more.
31
14.1M
         const auto put = [&](const auto& x) { return emit_bytes<false>(ctx, b, ix, x); };
_ZZN3glz6detail11minify_jsonITnDaXtlNS_4optsELj10ELb0ELb0ELb1ELb1EEETkNS_10is_contextERNS_7contextERPKcS7_RNSt3__112basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEEmEEvOT0_OT1_OT2_OT3_RT4_ENKUlRKT_E_clINS8_17basic_string_viewIcSB_EEEEDaSS_
Line
Count
Source
31
5.56k
         const auto put = [&](const auto& x) { return emit_bytes<false>(ctx, b, ix, x); };
_ZZN3glz6detail11minify_jsonITnDaXtlNS_4optsELj10ELb0ELb0ELb1ELb1EEETkNS_10is_contextERNS_7contextERPKcS7_RNSt3__112basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEEmEEvOT0_OT1_OT2_OT3_RT4_ENKUlRKT_E_clIcEEDaSS_
Line
Count
Source
31
48.0k
         const auto put = [&](const auto& x) { return emit_bytes<false>(ctx, b, ix, x); };
_ZZN3glz6detail11minify_jsonITnDaXtlNS_4optsELj10ELb0ELb0ELb1ELb1EEETkNS_10is_contextERNS_7contextERPKcS7_RNSt3__112basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEEmEEvOT0_OT1_OT2_OT3_RT4_ENKUlRKT_E_clIA5_cEEDaSS_
Line
Count
Source
31
3.11k
         const auto put = [&](const auto& x) { return emit_bytes<false>(ctx, b, ix, x); };
_ZZN3glz6detail11minify_jsonITnDaXtlNS_4optsELj10ELb0ELb0ELb1ELb1EEETkNS_10is_contextERNS_7contextERPKcS7_RNSt3__112basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEEmEEvOT0_OT1_OT2_OT3_RT4_ENKUlRKT_E_clIA6_cEEDaSS_
Line
Count
Source
31
1.28k
         const auto put = [&](const auto& x) { return emit_bytes<false>(ctx, b, ix, x); };
_ZZN3glz6detail11minify_jsonITnDaXtlNS_4optsELj10ELb0ELb1ELb1ELb1EEETkNS_10is_contextERNS_7contextERPKcS7_RNSt3__112basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEEmEEvOT0_OT1_OT2_OT3_RT4_ENKUlRKT_E_clINS8_17basic_string_viewIcSB_EEEEDaSS_
Line
Count
Source
31
4.18k
         const auto put = [&](const auto& x) { return emit_bytes<false>(ctx, b, ix, x); };
_ZZN3glz6detail11minify_jsonITnDaXtlNS_4optsELj10ELb0ELb1ELb1ELb1EEETkNS_10is_contextERNS_7contextERPKcS7_RNSt3__112basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEEmEEvOT0_OT1_OT2_OT3_RT4_ENKUlRKT_E_clIcEEDaSS_
Line
Count
Source
31
24.5k
         const auto put = [&](const auto& x) { return emit_bytes<false>(ctx, b, ix, x); };
_ZZN3glz6detail11minify_jsonITnDaXtlNS_4optsELj10ELb0ELb1ELb1ELb1EEETkNS_10is_contextERNS_7contextERPKcS7_RNSt3__112basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEEmEEvOT0_OT1_OT2_OT3_RT4_ENKUlRKT_E_clIA5_cEEDaSS_
Line
Count
Source
31
1.58k
         const auto put = [&](const auto& x) { return emit_bytes<false>(ctx, b, ix, x); };
_ZZN3glz6detail11minify_jsonITnDaXtlNS_4optsELj10ELb0ELb1ELb1ELb1EEETkNS_10is_contextERNS_7contextERPKcS7_RNSt3__112basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEEmEEvOT0_OT1_OT2_OT3_RT4_ENKUlRKT_E_clIA6_cEEDaSS_
Line
Count
Source
31
641
         const auto put = [&](const auto& x) { return emit_bytes<false>(ctx, b, ix, x); };
_ZZN3glz6detail11minify_jsonITnDaXtlNS_4optsELj10ELb1ELb1ELb1ELb1EEETkNS_10is_contextERNS_7contextERPKcS7_RNSt3__112basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEEmEEvOT0_OT1_OT2_OT3_RT4_ENKUlRKT_E_clINS8_17basic_string_viewIcSB_EEEEDaSS_
Line
Count
Source
31
2.39M
         const auto put = [&](const auto& x) { return emit_bytes<false>(ctx, b, ix, x); };
_ZZN3glz6detail11minify_jsonITnDaXtlNS_4optsELj10ELb1ELb1ELb1ELb1EEETkNS_10is_contextERNS_7contextERPKcS7_RNSt3__112basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEEmEEvOT0_OT1_OT2_OT3_RT4_ENKUlRKT_E_clIcEEDaSS_
Line
Count
Source
31
10.9M
         const auto put = [&](const auto& x) { return emit_bytes<false>(ctx, b, ix, x); };
_ZZN3glz6detail11minify_jsonITnDaXtlNS_4optsELj10ELb1ELb1ELb1ELb1EEETkNS_10is_contextERNS_7contextERPKcS7_RNSt3__112basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEEmEEvOT0_OT1_OT2_OT3_RT4_ENKUlRKT_E_clIA5_cEEDaSS_
Line
Count
Source
31
130k
         const auto put = [&](const auto& x) { return emit_bytes<false>(ctx, b, ix, x); };
_ZZN3glz6detail11minify_jsonITnDaXtlNS_4optsELj10ELb1ELb1ELb1ELb1EEETkNS_10is_contextERNS_7contextERPKcS7_RNSt3__112basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEEmEEvOT0_OT1_OT2_OT3_RT4_ENKUlRKT_E_clIA6_cEEDaSS_
Line
Count
Source
31
553k
         const auto put = [&](const auto& x) { return emit_bytes<false>(ctx, b, ix, x); };
_ZZN3glz6detail11minify_jsonITnDaXtlNS_4optsELj10ELb0ELb1ELb1ELb1EEETkNS_10is_contextERNS_7contextERPKcS7_RNSt3__15arrayIcLm64EEEmEEvOT0_OT1_OT2_OT3_RT4_ENKUlRKT_E_clINS8_17basic_string_viewIcNS8_11char_traitsIcEEEEEEDaSO_
Line
Count
Source
31
2.16k
         const auto put = [&](const auto& x) { return emit_bytes<false>(ctx, b, ix, x); };
_ZZN3glz6detail11minify_jsonITnDaXtlNS_4optsELj10ELb0ELb1ELb1ELb1EEETkNS_10is_contextERNS_7contextERPKcS7_RNSt3__15arrayIcLm64EEEmEEvOT0_OT1_OT2_OT3_RT4_ENKUlRKT_E_clIcEEDaSO_
Line
Count
Source
31
17.9k
         const auto put = [&](const auto& x) { return emit_bytes<false>(ctx, b, ix, x); };
_ZZN3glz6detail11minify_jsonITnDaXtlNS_4optsELj10ELb0ELb1ELb1ELb1EEETkNS_10is_contextERNS_7contextERPKcS7_RNSt3__15arrayIcLm64EEEmEEvOT0_OT1_OT2_OT3_RT4_ENKUlRKT_E_clIA5_cEEDaSO_
Line
Count
Source
31
672
         const auto put = [&](const auto& x) { return emit_bytes<false>(ctx, b, ix, x); };
_ZZN3glz6detail11minify_jsonITnDaXtlNS_4optsELj10ELb0ELb1ELb1ELb1EEETkNS_10is_contextERNS_7contextERPKcS7_RNSt3__15arrayIcLm64EEEmEEvOT0_OT1_OT2_OT3_RT4_ENKUlRKT_E_clIA6_cEEDaSO_
Line
Count
Source
31
220
         const auto put = [&](const auto& x) { return emit_bytes<false>(ctx, b, ix, x); };
32
33
26.4k
         auto ws_start = it;
34
26.4k
         uint64_t ws_size{};
35
36
7.21M
         auto skip_expected_whitespace = [&] {
37
7.21M
            auto new_ws_start = it;
38
7.21M
            if (ws_size && std::ptrdiff_t(ws_size) < end - it) [[likely]] {
39
2.67M
               skip_matching_ws(ws_start, it, ws_size);
40
2.67M
            }
41
42
7.21M
            if constexpr (Opts.null_terminated) {
43
35.5M
               while (whitespace_table[uint8_t(*it)]) {
44
28.3M
                  ++it;
45
28.3M
               }
46
            }
47
76.2k
            else {
48
77.3M
               while ((it < end) && whitespace_table[uint8_t(*it)]) {
49
77.2M
                  ++it;
50
77.2M
               }
51
76.2k
            }
52
7.21M
            ws_start = new_ws_start;
53
7.21M
            ws_size = size_t(it - new_ws_start);
54
7.21M
         };
_ZZN3glz6detail11minify_jsonITnDaXtlNS_4optsELj10ELb0ELb0ELb1ELb1EEETkNS_10is_contextERNS_7contextERPKcS7_RNSt3__112basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEEmEEvOT0_OT1_OT2_OT3_RT4_ENKUlvE_clEv
Line
Count
Source
36
40.4k
         auto skip_expected_whitespace = [&] {
37
40.4k
            auto new_ws_start = it;
38
40.4k
            if (ws_size && std::ptrdiff_t(ws_size) < end - it) [[likely]] {
39
27.5k
               skip_matching_ws(ws_start, it, ws_size);
40
27.5k
            }
41
42
            if constexpr (Opts.null_terminated) {
43
               while (whitespace_table[uint8_t(*it)]) {
44
                  ++it;
45
               }
46
            }
47
40.4k
            else {
48
38.7M
               while ((it < end) && whitespace_table[uint8_t(*it)]) {
49
38.6M
                  ++it;
50
38.6M
               }
51
40.4k
            }
52
40.4k
            ws_start = new_ws_start;
53
40.4k
            ws_size = size_t(it - new_ws_start);
54
40.4k
         };
_ZZN3glz6detail11minify_jsonITnDaXtlNS_4optsELj10ELb0ELb1ELb1ELb1EEETkNS_10is_contextERNS_7contextERPKcS7_RNSt3__112basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEEmEEvOT0_OT1_OT2_OT3_RT4_ENKUlvE_clEv
Line
Count
Source
36
20.6k
         auto skip_expected_whitespace = [&] {
37
20.6k
            auto new_ws_start = it;
38
20.6k
            if (ws_size && std::ptrdiff_t(ws_size) < end - it) [[likely]] {
39
13.4k
               skip_matching_ws(ws_start, it, ws_size);
40
13.4k
            }
41
42
            if constexpr (Opts.null_terminated) {
43
               while (whitespace_table[uint8_t(*it)]) {
44
                  ++it;
45
               }
46
            }
47
20.6k
            else {
48
19.3M
               while ((it < end) && whitespace_table[uint8_t(*it)]) {
49
19.3M
                  ++it;
50
19.3M
               }
51
20.6k
            }
52
20.6k
            ws_start = new_ws_start;
53
20.6k
            ws_size = size_t(it - new_ws_start);
54
20.6k
         };
_ZZN3glz6detail11minify_jsonITnDaXtlNS_4optsELj10ELb1ELb1ELb1ELb1EEETkNS_10is_contextERNS_7contextERPKcS7_RNSt3__112basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEEmEEvOT0_OT1_OT2_OT3_RT4_ENKUlvE_clEv
Line
Count
Source
36
7.14M
         auto skip_expected_whitespace = [&] {
37
7.14M
            auto new_ws_start = it;
38
7.14M
            if (ws_size && std::ptrdiff_t(ws_size) < end - it) [[likely]] {
39
2.62M
               skip_matching_ws(ws_start, it, ws_size);
40
2.62M
            }
41
42
7.14M
            if constexpr (Opts.null_terminated) {
43
35.5M
               while (whitespace_table[uint8_t(*it)]) {
44
28.3M
                  ++it;
45
28.3M
               }
46
            }
47
            else {
48
               while ((it < end) && whitespace_table[uint8_t(*it)]) {
49
                  ++it;
50
               }
51
            }
52
7.14M
            ws_start = new_ws_start;
53
7.14M
            ws_size = size_t(it - new_ws_start);
54
7.14M
         };
_ZZN3glz6detail11minify_jsonITnDaXtlNS_4optsELj10ELb0ELb1ELb1ELb1EEETkNS_10is_contextERNS_7contextERPKcS7_RNSt3__15arrayIcLm64EEEmEEvOT0_OT1_OT2_OT3_RT4_ENKUlvE_clEv
Line
Count
Source
36
15.1k
         auto skip_expected_whitespace = [&] {
37
15.1k
            auto new_ws_start = it;
38
15.1k
            if (ws_size && std::ptrdiff_t(ws_size) < end - it) [[likely]] {
39
9.19k
               skip_matching_ws(ws_start, it, ws_size);
40
9.19k
            }
41
42
            if constexpr (Opts.null_terminated) {
43
               while (whitespace_table[uint8_t(*it)]) {
44
                  ++it;
45
               }
46
            }
47
15.1k
            else {
48
19.2M
               while ((it < end) && whitespace_table[uint8_t(*it)]) {
49
19.2M
                  ++it;
50
19.2M
               }
51
15.1k
            }
52
15.1k
            ws_start = new_ws_start;
53
15.1k
            ws_size = size_t(it - new_ws_start);
54
15.1k
         };
55
56
7.63M
         auto skip_whitespace = [&] {
57
7.63M
            if constexpr (Opts.null_terminated) {
58
11.6M
               while (whitespace_table[uint8_t(*it)]) {
59
4.04M
                  ++it;
60
4.04M
               }
61
            }
62
49.4k
            else {
63
459k
               while ((it < end) && whitespace_table[uint8_t(*it)]) {
64
410k
                  ++it;
65
410k
               }
66
49.4k
            }
67
7.63M
         };
_ZZN3glz6detail11minify_jsonITnDaXtlNS_4optsELj10ELb0ELb0ELb1ELb1EEETkNS_10is_contextERNS_7contextERPKcS7_RNSt3__112basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEEmEEvOT0_OT1_OT2_OT3_RT4_ENKUlvE0_clEv
Line
Count
Source
56
24.4k
         auto skip_whitespace = [&] {
57
            if constexpr (Opts.null_terminated) {
58
               while (whitespace_table[uint8_t(*it)]) {
59
                  ++it;
60
               }
61
            }
62
24.4k
            else {
63
231k
               while ((it < end) && whitespace_table[uint8_t(*it)]) {
64
206k
                  ++it;
65
206k
               }
66
24.4k
            }
67
24.4k
         };
_ZZN3glz6detail11minify_jsonITnDaXtlNS_4optsELj10ELb0ELb1ELb1ELb1EEETkNS_10is_contextERNS_7contextERPKcS7_RNSt3__112basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEEmEEvOT0_OT1_OT2_OT3_RT4_ENKUlvE0_clEv
Line
Count
Source
56
14.9k
         auto skip_whitespace = [&] {
57
            if constexpr (Opts.null_terminated) {
58
               while (whitespace_table[uint8_t(*it)]) {
59
                  ++it;
60
               }
61
            }
62
14.9k
            else {
63
122k
               while ((it < end) && whitespace_table[uint8_t(*it)]) {
64
107k
                  ++it;
65
107k
               }
66
14.9k
            }
67
14.9k
         };
_ZZN3glz6detail11minify_jsonITnDaXtlNS_4optsELj10ELb1ELb1ELb1ELb1EEETkNS_10is_contextERNS_7contextERPKcS7_RNSt3__112basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEEmEEvOT0_OT1_OT2_OT3_RT4_ENKUlvE0_clEv
Line
Count
Source
56
7.58M
         auto skip_whitespace = [&] {
57
7.58M
            if constexpr (Opts.null_terminated) {
58
11.6M
               while (whitespace_table[uint8_t(*it)]) {
59
4.04M
                  ++it;
60
4.04M
               }
61
            }
62
            else {
63
               while ((it < end) && whitespace_table[uint8_t(*it)]) {
64
                  ++it;
65
               }
66
            }
67
7.58M
         };
_ZZN3glz6detail11minify_jsonITnDaXtlNS_4optsELj10ELb0ELb1ELb1ELb1EEETkNS_10is_contextERNS_7contextERPKcS7_RNSt3__15arrayIcLm64EEEmEEvOT0_OT1_OT2_OT3_RT4_ENKUlvE0_clEv
Line
Count
Source
56
9.97k
         auto skip_whitespace = [&] {
57
            if constexpr (Opts.null_terminated) {
58
               while (whitespace_table[uint8_t(*it)]) {
59
                  ++it;
60
               }
61
            }
62
9.97k
            else {
63
105k
               while ((it < end) && whitespace_table[uint8_t(*it)]) {
64
95.5k
                  ++it;
65
95.5k
               }
66
9.97k
            }
67
9.97k
         };
68
69
26.4k
         skip_whitespace();
70
71
14.8M
         while ([&]() -> bool {
72
14.8M
            if constexpr (Opts.null_terminated) {
73
14.7M
               return true;
74
            }
75
125k
            else {
76
125k
               return it < end;
77
125k
            }
78
14.8M
         }()) {
_ZZN3glz6detail11minify_jsonITnDaXtlNS_4optsELj10ELb0ELb0ELb1ELb1EEETkNS_10is_contextERNS_7contextERPKcS7_RNSt3__112basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEEmEEvOT0_OT1_OT2_OT3_RT4_ENKUlvE1_clEv
Line
Count
Source
71
64.9k
         while ([&]() -> bool {
72
            if constexpr (Opts.null_terminated) {
73
               return true;
74
            }
75
64.9k
            else {
76
64.9k
               return it < end;
77
64.9k
            }
78
64.9k
         }()) {
_ZZN3glz6detail11minify_jsonITnDaXtlNS_4optsELj10ELb0ELb1ELb1ELb1EEETkNS_10is_contextERNS_7contextERPKcS7_RNSt3__112basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEEmEEvOT0_OT1_OT2_OT3_RT4_ENKUlvE1_clEv
Line
Count
Source
71
35.6k
         while ([&]() -> bool {
72
            if constexpr (Opts.null_terminated) {
73
               return true;
74
            }
75
35.6k
            else {
76
35.6k
               return it < end;
77
35.6k
            }
78
35.6k
         }()) {
_ZZN3glz6detail11minify_jsonITnDaXtlNS_4optsELj10ELb1ELb1ELb1ELb1EEETkNS_10is_contextERNS_7contextERPKcS7_RNSt3__112basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEEmEEvOT0_OT1_OT2_OT3_RT4_ENKUlvE1_clEv
Line
Count
Source
71
14.7M
         while ([&]() -> bool {
72
14.7M
            if constexpr (Opts.null_terminated) {
73
14.7M
               return true;
74
            }
75
            else {
76
               return it < end;
77
            }
78
14.7M
         }()) {
_ZZN3glz6detail11minify_jsonITnDaXtlNS_4optsELj10ELb0ELb1ELb1ELb1EEETkNS_10is_contextERNS_7contextERPKcS7_RNSt3__15arrayIcLm64EEEmEEvOT0_OT1_OT2_OT3_RT4_ENKUlvE1_clEv
Line
Count
Source
71
25.1k
         while ([&]() -> bool {
72
            if constexpr (Opts.null_terminated) {
73
               return true;
74
            }
75
25.1k
            else {
76
25.1k
               return it < end;
77
25.1k
            }
78
25.1k
         }()) {
79
14.8M
            switch (json_types[uint8_t(*it)]) {
80
1.40M
            case String: {
81
1.40M
               const auto value = read_json_string(ctx, it, end);
82
1.40M
               if (bool(ctx.error)) [[unlikely]] {
83
515
                  return;
84
515
               }
85
               // non-empty: the scanner reports an empty view as an error
86
1.40M
               if (not put(value)) [[unlikely]] {
87
60
                  return;
88
60
               }
89
1.40M
               skip_whitespace();
90
1.40M
               break;
91
1.40M
            }
92
4.42M
            case Comma: {
93
4.42M
               if (not put(',')) [[unlikely]] {
94
34
                  return;
95
34
               }
96
4.42M
               ++it;
97
4.42M
               skip_expected_whitespace();
98
4.42M
               break;
99
4.42M
            }
100
991k
            case Number: {
101
991k
               const auto value = read_json_number<Opts.null_terminated>(it, end);
102
               // non-empty: a Number match is one valid character
103
991k
               if (not put(value)) [[unlikely]] {
104
32
                  return;
105
32
               }
106
991k
               skip_whitespace();
107
991k
               break;
108
991k
            }
109
1.10M
            case Colon: {
110
1.10M
               if (not put(':')) [[unlikely]] {
111
5
                  return;
112
5
               }
113
1.10M
               ++it;
114
1.10M
               skip_whitespace();
115
1.10M
               break;
116
1.10M
            }
117
600k
            case Array_Start: {
118
600k
               if (not put('[')) [[unlikely]] {
119
32
                  return;
120
32
               }
121
600k
               ++it;
122
600k
               skip_expected_whitespace();
123
600k
               break;
124
600k
            }
125
576k
            case Array_End: {
126
576k
               if (not put(']')) [[unlikely]] {
127
9
                  return;
128
9
               }
129
576k
               ++it;
130
576k
               skip_whitespace();
131
576k
               break;
132
576k
            }
133
51.2k
            case Null: {
134
               // The type table matched on the first byte alone; see match_literal for why writing
135
               // the literal from the writer's own spelling needs the rest of it checked. Stepping
136
               // over it unchecked also puts `it` past `end`, and from there the loop goes on
137
               // minifying whatever follows the document into an output sized for the document.
138
51.2k
               if (not match_literal<"null">(ctx, it, end)) [[unlikely]] {
139
580
                  return;
140
580
               }
141
50.6k
               if (not put("null")) [[unlikely]] {
142
11
                  return;
143
11
               }
144
50.6k
               skip_whitespace();
145
50.6k
               break;
146
50.6k
            }
147
642k
            case Bool: {
148
642k
               if (*it == 't') {
149
86.1k
                  if (not match_literal<"true">(ctx, it, end)) [[unlikely]] {
150
513
                     return;
151
513
                  }
152
85.6k
                  if (not put("true")) [[unlikely]] {
153
11
                     return;
154
11
                  }
155
85.6k
                  skip_whitespace();
156
85.6k
                  break;
157
85.6k
               }
158
556k
               else {
159
556k
                  if (not match_literal<"false">(ctx, it, end)) [[unlikely]] {
160
611
                     return;
161
611
                  }
162
555k
                  if (not put("false")) [[unlikely]] {
163
11
                     return;
164
11
                  }
165
555k
                  skip_whitespace();
166
555k
                  break;
167
555k
               }
168
642k
            }
169
2.18M
            case Object_Start: {
170
2.18M
               if (not put('{')) [[unlikely]] {
171
30
                  return;
172
30
               }
173
2.18M
               ++it;
174
2.18M
               skip_expected_whitespace();
175
2.18M
               break;
176
2.18M
            }
177
2.16M
            case Object_End: {
178
2.16M
               if (not put('}')) [[unlikely]] {
179
8
                  return;
180
8
               }
181
2.16M
               ++it;
182
2.16M
               skip_whitespace();
183
2.16M
               break;
184
2.16M
            }
185
678k
            case Comment: {
186
678k
               if constexpr (Opts.comments) {
187
678k
                  const auto comment = read_jsonc_comment(ctx, it, end);
188
678k
                  if (bool(ctx.error)) [[unlikely]] {
189
409
                     return;
190
409
                  }
191
                  // A line comment is dropped rather than written out. Minifying is what removes
192
                  // the newline that ends it, and a line comment with no line break behind it
193
                  // comments out the whole rest of the output.
194
677k
                  if (not comment.line) {
195
                     // non-empty: an empty view comes with an error
196
11.4k
                     if (not put(comment.text)) [[unlikely]] {
197
52
                        return;
198
52
                     }
199
11.4k
                  }
200
677k
                  skip_whitespace();
201
677k
                  break;
202
               }
203
570
               else {
204
570
                  [[fallthrough]];
205
570
               }
206
678k
            }
207
698k
            [[unlikely]] default: {
208
               // A null terminated run carries no bound in its loop condition, so it ends here, on
209
               // the terminator, which is not a JSON token. Reaching it is the end of the document
210
               // rather than an error -- unclassified is how the type table reports both, and
211
               // without this the minifier left syntax_error behind on every input it was ever
212
               // given, valid or not, which is what made its error not worth returning.
213
698k
               if constexpr (Opts.null_terminated) {
214
686k
                  if (it >= end) {
215
10.4k
                     return;
216
10.4k
                  }
217
686k
               }
218
675k
               ctx.error = error_code::syntax_error;
219
698k
               return;
220
678k
            }
221
14.8M
            }
222
14.8M
         }
223
26.4k
      }
_ZN3glz6detail11minify_jsonITnDaXtlNS_4optsELj10ELb0ELb0ELb1ELb1EEETkNS_10is_contextERNS_7contextERPKcS7_RNSt3__112basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEEmEEvOT0_OT1_OT2_OT3_RT4_
Line
Count
Source
18
6.86k
      {
19
6.86k
         using enum json_type;
20
21
         // Every write below goes through this, and the dump it makes is unchecked: the caller's
22
         // one-shot sizing covers a resizable destination, because minifying only ever removes
23
         // bytes, so the input's length is room enough.
24
         //
25
         // A bounded destination cannot be grown, and asking it for the input's length up front
26
         // refuses a buffer that fits the result -- sizing the output to the minified length is the
27
         // obvious thing to do, and `{ "a" : 1 }` into a 7 byte buffer has to work. So each write
28
         // asks for exactly what it stores instead; see emit_bytes for where that count comes from.
29
         // None of it survives for a resizable destination, which keeps the unchecked dumps and
30
         // nothing more.
31
6.86k
         const auto put = [&](const auto& x) { return emit_bytes<false>(ctx, b, ix, x); };
32
33
6.86k
         auto ws_start = it;
34
6.86k
         uint64_t ws_size{};
35
36
6.86k
         auto skip_expected_whitespace = [&] {
37
6.86k
            auto new_ws_start = it;
38
6.86k
            if (ws_size && std::ptrdiff_t(ws_size) < end - it) [[likely]] {
39
6.86k
               skip_matching_ws(ws_start, it, ws_size);
40
6.86k
            }
41
42
6.86k
            if constexpr (Opts.null_terminated) {
43
6.86k
               while (whitespace_table[uint8_t(*it)]) {
44
6.86k
                  ++it;
45
6.86k
               }
46
6.86k
            }
47
6.86k
            else {
48
6.86k
               while ((it < end) && whitespace_table[uint8_t(*it)]) {
49
6.86k
                  ++it;
50
6.86k
               }
51
6.86k
            }
52
6.86k
            ws_start = new_ws_start;
53
6.86k
            ws_size = size_t(it - new_ws_start);
54
6.86k
         };
55
56
6.86k
         auto skip_whitespace = [&] {
57
6.86k
            if constexpr (Opts.null_terminated) {
58
6.86k
               while (whitespace_table[uint8_t(*it)]) {
59
6.86k
                  ++it;
60
6.86k
               }
61
6.86k
            }
62
6.86k
            else {
63
6.86k
               while ((it < end) && whitespace_table[uint8_t(*it)]) {
64
6.86k
                  ++it;
65
6.86k
               }
66
6.86k
            }
67
6.86k
         };
68
69
6.86k
         skip_whitespace();
70
71
64.9k
         while ([&]() -> bool {
72
64.9k
            if constexpr (Opts.null_terminated) {
73
64.9k
               return true;
74
64.9k
            }
75
64.9k
            else {
76
64.9k
               return it < end;
77
64.9k
            }
78
64.9k
         }()) {
79
63.8k
            switch (json_types[uint8_t(*it)]) {
80
2.95k
            case String: {
81
2.95k
               const auto value = read_json_string(ctx, it, end);
82
2.95k
               if (bool(ctx.error)) [[unlikely]] {
83
198
                  return;
84
198
               }
85
               // non-empty: the scanner reports an empty view as an error
86
2.75k
               if (not put(value)) [[unlikely]] {
87
0
                  return;
88
0
               }
89
2.75k
               skip_whitespace();
90
2.75k
               break;
91
2.75k
            }
92
14.4k
            case Comma: {
93
14.4k
               if (not put(',')) [[unlikely]] {
94
0
                  return;
95
0
               }
96
14.4k
               ++it;
97
14.4k
               skip_expected_whitespace();
98
14.4k
               break;
99
14.4k
            }
100
2.80k
            case Number: {
101
2.80k
               const auto value = read_json_number<Opts.null_terminated>(it, end);
102
               // non-empty: a Number match is one valid character
103
2.80k
               if (not put(value)) [[unlikely]] {
104
0
                  return;
105
0
               }
106
2.80k
               skip_whitespace();
107
2.80k
               break;
108
2.80k
            }
109
2.59k
            case Colon: {
110
2.59k
               if (not put(':')) [[unlikely]] {
111
0
                  return;
112
0
               }
113
2.59k
               ++it;
114
2.59k
               skip_whitespace();
115
2.59k
               break;
116
2.59k
            }
117
12.1k
            case Array_Start: {
118
12.1k
               if (not put('[')) [[unlikely]] {
119
0
                  return;
120
0
               }
121
12.1k
               ++it;
122
12.1k
               skip_expected_whitespace();
123
12.1k
               break;
124
12.1k
            }
125
2.50k
            case Array_End: {
126
2.50k
               if (not put(']')) [[unlikely]] {
127
0
                  return;
128
0
               }
129
2.50k
               ++it;
130
2.50k
               skip_whitespace();
131
2.50k
               break;
132
2.50k
            }
133
1.55k
            case Null: {
134
               // The type table matched on the first byte alone; see match_literal for why writing
135
               // the literal from the writer's own spelling needs the rest of it checked. Stepping
136
               // over it unchecked also puts `it` past `end`, and from there the loop goes on
137
               // minifying whatever follows the document into an output sized for the document.
138
1.55k
               if (not match_literal<"null">(ctx, it, end)) [[unlikely]] {
139
234
                  return;
140
234
               }
141
1.31k
               if (not put("null")) [[unlikely]] {
142
0
                  return;
143
0
               }
144
1.31k
               skip_whitespace();
145
1.31k
               break;
146
1.31k
            }
147
3.53k
            case Bool: {
148
3.53k
               if (*it == 't') {
149
2.01k
                  if (not match_literal<"true">(ctx, it, end)) [[unlikely]] {
150
210
                     return;
151
210
                  }
152
1.80k
                  if (not put("true")) [[unlikely]] {
153
0
                     return;
154
0
                  }
155
1.80k
                  skip_whitespace();
156
1.80k
                  break;
157
1.80k
               }
158
1.52k
               else {
159
1.52k
                  if (not match_literal<"false">(ctx, it, end)) [[unlikely]] {
160
246
                     return;
161
246
                  }
162
1.28k
                  if (not put("false")) [[unlikely]] {
163
0
                     return;
164
0
                  }
165
1.28k
                  skip_whitespace();
166
1.28k
                  break;
167
1.28k
               }
168
3.53k
            }
169
13.7k
            case Object_Start: {
170
13.7k
               if (not put('{')) [[unlikely]] {
171
0
                  return;
172
0
               }
173
13.7k
               ++it;
174
13.7k
               skip_expected_whitespace();
175
13.7k
               break;
176
13.7k
            }
177
2.57k
            case Object_End: {
178
2.57k
               if (not put('}')) [[unlikely]] {
179
0
                  return;
180
0
               }
181
2.57k
               ++it;
182
2.57k
               skip_whitespace();
183
2.57k
               break;
184
2.57k
            }
185
570
            case Comment: {
186
               if constexpr (Opts.comments) {
187
                  const auto comment = read_jsonc_comment(ctx, it, end);
188
                  if (bool(ctx.error)) [[unlikely]] {
189
                     return;
190
                  }
191
                  // A line comment is dropped rather than written out. Minifying is what removes
192
                  // the newline that ends it, and a line comment with no line break behind it
193
                  // comments out the whole rest of the output.
194
                  if (not comment.line) {
195
                     // non-empty: an empty view comes with an error
196
                     if (not put(comment.text)) [[unlikely]] {
197
                        return;
198
                     }
199
                  }
200
                  skip_whitespace();
201
                  break;
202
               }
203
570
               else {
204
570
                  [[fallthrough]];
205
570
               }
206
570
            }
207
4.92k
            [[unlikely]] default: {
208
               // A null terminated run carries no bound in its loop condition, so it ends here, on
209
               // the terminator, which is not a JSON token. Reaching it is the end of the document
210
               // rather than an error -- unclassified is how the type table reports both, and
211
               // without this the minifier left syntax_error behind on every input it was ever
212
               // given, valid or not, which is what made its error not worth returning.
213
               if constexpr (Opts.null_terminated) {
214
                  if (it >= end) {
215
                     return;
216
                  }
217
               }
218
4.92k
               ctx.error = error_code::syntax_error;
219
4.92k
               return;
220
570
            }
221
63.8k
            }
222
63.8k
         }
223
6.86k
      }
_ZN3glz6detail11minify_jsonITnDaXtlNS_4optsELj10ELb0ELb1ELb1ELb1EEETkNS_10is_contextERNS_7contextERPKcS7_RNSt3__112basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEEmEEvOT0_OT1_OT2_OT3_RT4_
Line
Count
Source
18
3.43k
      {
19
3.43k
         using enum json_type;
20
21
         // Every write below goes through this, and the dump it makes is unchecked: the caller's
22
         // one-shot sizing covers a resizable destination, because minifying only ever removes
23
         // bytes, so the input's length is room enough.
24
         //
25
         // A bounded destination cannot be grown, and asking it for the input's length up front
26
         // refuses a buffer that fits the result -- sizing the output to the minified length is the
27
         // obvious thing to do, and `{ "a" : 1 }` into a 7 byte buffer has to work. So each write
28
         // asks for exactly what it stores instead; see emit_bytes for where that count comes from.
29
         // None of it survives for a resizable destination, which keeps the unchecked dumps and
30
         // nothing more.
31
3.43k
         const auto put = [&](const auto& x) { return emit_bytes<false>(ctx, b, ix, x); };
32
33
3.43k
         auto ws_start = it;
34
3.43k
         uint64_t ws_size{};
35
36
3.43k
         auto skip_expected_whitespace = [&] {
37
3.43k
            auto new_ws_start = it;
38
3.43k
            if (ws_size && std::ptrdiff_t(ws_size) < end - it) [[likely]] {
39
3.43k
               skip_matching_ws(ws_start, it, ws_size);
40
3.43k
            }
41
42
3.43k
            if constexpr (Opts.null_terminated) {
43
3.43k
               while (whitespace_table[uint8_t(*it)]) {
44
3.43k
                  ++it;
45
3.43k
               }
46
3.43k
            }
47
3.43k
            else {
48
3.43k
               while ((it < end) && whitespace_table[uint8_t(*it)]) {
49
3.43k
                  ++it;
50
3.43k
               }
51
3.43k
            }
52
3.43k
            ws_start = new_ws_start;
53
3.43k
            ws_size = size_t(it - new_ws_start);
54
3.43k
         };
55
56
3.43k
         auto skip_whitespace = [&] {
57
3.43k
            if constexpr (Opts.null_terminated) {
58
3.43k
               while (whitespace_table[uint8_t(*it)]) {
59
3.43k
                  ++it;
60
3.43k
               }
61
3.43k
            }
62
3.43k
            else {
63
3.43k
               while ((it < end) && whitespace_table[uint8_t(*it)]) {
64
3.43k
                  ++it;
65
3.43k
               }
66
3.43k
            }
67
3.43k
         };
68
69
3.43k
         skip_whitespace();
70
71
35.6k
         while ([&]() -> bool {
72
35.6k
            if constexpr (Opts.null_terminated) {
73
35.6k
               return true;
74
35.6k
            }
75
35.6k
            else {
76
35.6k
               return it < end;
77
35.6k
            }
78
35.6k
         }()) {
79
34.4k
            switch (json_types[uint8_t(*it)]) {
80
1.53k
            case String: {
81
1.53k
               const auto value = read_json_string(ctx, it, end);
82
1.53k
               if (bool(ctx.error)) [[unlikely]] {
83
110
                  return;
84
110
               }
85
               // non-empty: the scanner reports an empty view as an error
86
1.42k
               if (not put(value)) [[unlikely]] {
87
0
                  return;
88
0
               }
89
1.42k
               skip_whitespace();
90
1.42k
               break;
91
1.42k
            }
92
7.30k
            case Comma: {
93
7.30k
               if (not put(',')) [[unlikely]] {
94
0
                  return;
95
0
               }
96
7.30k
               ++it;
97
7.30k
               skip_expected_whitespace();
98
7.30k
               break;
99
7.30k
            }
100
1.44k
            case Number: {
101
1.44k
               const auto value = read_json_number<Opts.null_terminated>(it, end);
102
               // non-empty: a Number match is one valid character
103
1.44k
               if (not put(value)) [[unlikely]] {
104
0
                  return;
105
0
               }
106
1.44k
               skip_whitespace();
107
1.44k
               break;
108
1.44k
            }
109
1.33k
            case Colon: {
110
1.33k
               if (not put(':')) [[unlikely]] {
111
0
                  return;
112
0
               }
113
1.33k
               ++it;
114
1.33k
               skip_whitespace();
115
1.33k
               break;
116
1.33k
            }
117
6.34k
            case Array_Start: {
118
6.34k
               if (not put('[')) [[unlikely]] {
119
0
                  return;
120
0
               }
121
6.34k
               ++it;
122
6.34k
               skip_expected_whitespace();
123
6.34k
               break;
124
6.34k
            }
125
1.25k
            case Array_End: {
126
1.25k
               if (not put(']')) [[unlikely]] {
127
0
                  return;
128
0
               }
129
1.25k
               ++it;
130
1.25k
               skip_whitespace();
131
1.25k
               break;
132
1.25k
            }
133
777
            case Null: {
134
               // The type table matched on the first byte alone; see match_literal for why writing
135
               // the literal from the writer's own spelling needs the rest of it checked. Stepping
136
               // over it unchecked also puts `it` past `end`, and from there the loop goes on
137
               // minifying whatever follows the document into an output sized for the document.
138
777
               if (not match_literal<"null">(ctx, it, end)) [[unlikely]] {
139
118
                  return;
140
118
               }
141
659
               if (not put("null")) [[unlikely]] {
142
0
                  return;
143
0
               }
144
659
               skip_whitespace();
145
659
               break;
146
659
            }
147
1.79k
            case Bool: {
148
1.79k
               if (*it == 't') {
149
1.03k
                  if (not match_literal<"true">(ctx, it, end)) [[unlikely]] {
150
105
                     return;
151
105
                  }
152
926
                  if (not put("true")) [[unlikely]] {
153
0
                     return;
154
0
                  }
155
926
                  skip_whitespace();
156
926
                  break;
157
926
               }
158
765
               else {
159
765
                  if (not match_literal<"false">(ctx, it, end)) [[unlikely]] {
160
124
                     return;
161
124
                  }
162
641
                  if (not put("false")) [[unlikely]] {
163
0
                     return;
164
0
                  }
165
641
                  skip_whitespace();
166
641
                  break;
167
641
               }
168
1.79k
            }
169
6.99k
            case Object_Start: {
170
6.99k
               if (not put('{')) [[unlikely]] {
171
0
                  return;
172
0
               }
173
6.99k
               ++it;
174
6.99k
               skip_expected_whitespace();
175
6.99k
               break;
176
6.99k
            }
177
1.30k
            case Object_End: {
178
1.30k
               if (not put('}')) [[unlikely]] {
179
0
                  return;
180
0
               }
181
1.30k
               ++it;
182
1.30k
               skip_whitespace();
183
1.30k
               break;
184
1.30k
            }
185
2.69k
            case Comment: {
186
2.69k
               if constexpr (Opts.comments) {
187
2.69k
                  const auto comment = read_jsonc_comment(ctx, it, end);
188
2.69k
                  if (bool(ctx.error)) [[unlikely]] {
189
141
                     return;
190
141
                  }
191
                  // A line comment is dropped rather than written out. Minifying is what removes
192
                  // the newline that ends it, and a line comment with no line break behind it
193
                  // comments out the whole rest of the output.
194
2.55k
                  if (not comment.line) {
195
                     // non-empty: an empty view comes with an error
196
1.31k
                     if (not put(comment.text)) [[unlikely]] {
197
0
                        return;
198
0
                     }
199
1.31k
                  }
200
2.55k
                  skip_whitespace();
201
2.55k
                  break;
202
               }
203
               else {
204
                  [[fallthrough]];
205
               }
206
2.69k
            }
207
4.38k
            [[unlikely]] default: {
208
               // A null terminated run carries no bound in its loop condition, so it ends here, on
209
               // the terminator, which is not a JSON token. Reaching it is the end of the document
210
               // rather than an error -- unclassified is how the type table reports both, and
211
               // without this the minifier left syntax_error behind on every input it was ever
212
               // given, valid or not, which is what made its error not worth returning.
213
               if constexpr (Opts.null_terminated) {
214
                  if (it >= end) {
215
                     return;
216
                  }
217
               }
218
4.38k
               ctx.error = error_code::syntax_error;
219
4.38k
               return;
220
2.69k
            }
221
34.4k
            }
222
34.4k
         }
223
3.43k
      }
_ZN3glz6detail11minify_jsonITnDaXtlNS_4optsELj10ELb1ELb1ELb1ELb1EEETkNS_10is_contextERNS_7contextERPKcS7_RNSt3__112basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEEmEEvOT0_OT1_OT2_OT3_RT4_
Line
Count
Source
18
12.7k
      {
19
12.7k
         using enum json_type;
20
21
         // Every write below goes through this, and the dump it makes is unchecked: the caller's
22
         // one-shot sizing covers a resizable destination, because minifying only ever removes
23
         // bytes, so the input's length is room enough.
24
         //
25
         // A bounded destination cannot be grown, and asking it for the input's length up front
26
         // refuses a buffer that fits the result -- sizing the output to the minified length is the
27
         // obvious thing to do, and `{ "a" : 1 }` into a 7 byte buffer has to work. So each write
28
         // asks for exactly what it stores instead; see emit_bytes for where that count comes from.
29
         // None of it survives for a resizable destination, which keeps the unchecked dumps and
30
         // nothing more.
31
12.7k
         const auto put = [&](const auto& x) { return emit_bytes<false>(ctx, b, ix, x); };
32
33
12.7k
         auto ws_start = it;
34
12.7k
         uint64_t ws_size{};
35
36
12.7k
         auto skip_expected_whitespace = [&] {
37
12.7k
            auto new_ws_start = it;
38
12.7k
            if (ws_size && std::ptrdiff_t(ws_size) < end - it) [[likely]] {
39
12.7k
               skip_matching_ws(ws_start, it, ws_size);
40
12.7k
            }
41
42
12.7k
            if constexpr (Opts.null_terminated) {
43
12.7k
               while (whitespace_table[uint8_t(*it)]) {
44
12.7k
                  ++it;
45
12.7k
               }
46
12.7k
            }
47
12.7k
            else {
48
12.7k
               while ((it < end) && whitespace_table[uint8_t(*it)]) {
49
12.7k
                  ++it;
50
12.7k
               }
51
12.7k
            }
52
12.7k
            ws_start = new_ws_start;
53
12.7k
            ws_size = size_t(it - new_ws_start);
54
12.7k
         };
55
56
12.7k
         auto skip_whitespace = [&] {
57
12.7k
            if constexpr (Opts.null_terminated) {
58
12.7k
               while (whitespace_table[uint8_t(*it)]) {
59
12.7k
                  ++it;
60
12.7k
               }
61
12.7k
            }
62
12.7k
            else {
63
12.7k
               while ((it < end) && whitespace_table[uint8_t(*it)]) {
64
12.7k
                  ++it;
65
12.7k
               }
66
12.7k
            }
67
12.7k
         };
68
69
12.7k
         skip_whitespace();
70
71
14.7M
         while ([&]() -> bool {
72
14.7M
            if constexpr (Opts.null_terminated) {
73
14.7M
               return true;
74
14.7M
            }
75
14.7M
            else {
76
14.7M
               return it < end;
77
14.7M
            }
78
14.7M
         }()) {
79
14.7M
            switch (json_types[uint8_t(*it)]) {
80
1.39M
            case String: {
81
1.39M
               const auto value = read_json_string(ctx, it, end);
82
1.39M
               if (bool(ctx.error)) [[unlikely]] {
83
110
                  return;
84
110
               }
85
               // non-empty: the scanner reports an empty view as an error
86
1.39M
               if (not put(value)) [[unlikely]] {
87
0
                  return;
88
0
               }
89
1.39M
               skip_whitespace();
90
1.39M
               break;
91
1.39M
            }
92
4.40M
            case Comma: {
93
4.40M
               if (not put(',')) [[unlikely]] {
94
0
                  return;
95
0
               }
96
4.40M
               ++it;
97
4.40M
               skip_expected_whitespace();
98
4.40M
               break;
99
4.40M
            }
100
986k
            case Number: {
101
986k
               const auto value = read_json_number<Opts.null_terminated>(it, end);
102
               // non-empty: a Number match is one valid character
103
986k
               if (not put(value)) [[unlikely]] {
104
0
                  return;
105
0
               }
106
986k
               skip_whitespace();
107
986k
               break;
108
986k
            }
109
1.09M
            case Colon: {
110
1.09M
               if (not put(':')) [[unlikely]] {
111
0
                  return;
112
0
               }
113
1.09M
               ++it;
114
1.09M
               skip_whitespace();
115
1.09M
               break;
116
1.09M
            }
117
576k
            case Array_Start: {
118
576k
               if (not put('[')) [[unlikely]] {
119
0
                  return;
120
0
               }
121
576k
               ++it;
122
576k
               skip_expected_whitespace();
123
576k
               break;
124
576k
            }
125
571k
            case Array_End: {
126
571k
               if (not put(']')) [[unlikely]] {
127
0
                  return;
128
0
               }
129
571k
               ++it;
130
571k
               skip_whitespace();
131
571k
               break;
132
571k
            }
133
48.5k
            case Null: {
134
               // The type table matched on the first byte alone; see match_literal for why writing
135
               // the literal from the writer's own spelling needs the rest of it checked. Stepping
136
               // over it unchecked also puts `it` past `end`, and from there the loop goes on
137
               // minifying whatever follows the document into an output sized for the document.
138
48.5k
               if (not match_literal<"null">(ctx, it, end)) [[unlikely]] {
139
118
                  return;
140
118
               }
141
48.4k
               if (not put("null")) [[unlikely]] {
142
0
                  return;
143
0
               }
144
48.4k
               skip_whitespace();
145
48.4k
               break;
146
48.4k
            }
147
636k
            case Bool: {
148
636k
               if (*it == 't') {
149
82.6k
                  if (not match_literal<"true">(ctx, it, end)) [[unlikely]] {
150
105
                     return;
151
105
                  }
152
82.5k
                  if (not put("true")) [[unlikely]] {
153
0
                     return;
154
0
                  }
155
82.5k
                  skip_whitespace();
156
82.5k
                  break;
157
82.5k
               }
158
553k
               else {
159
553k
                  if (not match_literal<"false">(ctx, it, end)) [[unlikely]] {
160
124
                     return;
161
124
                  }
162
553k
                  if (not put("false")) [[unlikely]] {
163
0
                     return;
164
0
                  }
165
553k
                  skip_whitespace();
166
553k
                  break;
167
553k
               }
168
636k
            }
169
2.16M
            case Object_Start: {
170
2.16M
               if (not put('{')) [[unlikely]] {
171
0
                  return;
172
0
               }
173
2.16M
               ++it;
174
2.16M
               skip_expected_whitespace();
175
2.16M
               break;
176
2.16M
            }
177
2.15M
            case Object_End: {
178
2.15M
               if (not put('}')) [[unlikely]] {
179
0
                  return;
180
0
               }
181
2.15M
               ++it;
182
2.15M
               skip_whitespace();
183
2.15M
               break;
184
2.15M
            }
185
674k
            case Comment: {
186
674k
               if constexpr (Opts.comments) {
187
674k
                  const auto comment = read_jsonc_comment(ctx, it, end);
188
674k
                  if (bool(ctx.error)) [[unlikely]] {
189
141
                     return;
190
141
                  }
191
                  // A line comment is dropped rather than written out. Minifying is what removes
192
                  // the newline that ends it, and a line comment with no line break behind it
193
                  // comments out the whole rest of the output.
194
673k
                  if (not comment.line) {
195
                     // non-empty: an empty view comes with an error
196
9.63k
                     if (not put(comment.text)) [[unlikely]] {
197
0
                        return;
198
0
                     }
199
9.63k
                  }
200
673k
                  skip_whitespace();
201
673k
                  break;
202
               }
203
               else {
204
                  [[fallthrough]];
205
               }
206
674k
            }
207
686k
            [[unlikely]] default: {
208
               // A null terminated run carries no bound in its loop condition, so it ends here, on
209
               // the terminator, which is not a JSON token. Reaching it is the end of the document
210
               // rather than an error -- unclassified is how the type table reports both, and
211
               // without this the minifier left syntax_error behind on every input it was ever
212
               // given, valid or not, which is what made its error not worth returning.
213
686k
               if constexpr (Opts.null_terminated) {
214
686k
                  if (it >= end) {
215
10.4k
                     return;
216
10.4k
                  }
217
686k
               }
218
675k
               ctx.error = error_code::syntax_error;
219
686k
               return;
220
674k
            }
221
14.7M
            }
222
14.7M
         }
223
12.7k
      }
_ZN3glz6detail11minify_jsonITnDaXtlNS_4optsELj10ELb0ELb1ELb1ELb1EEETkNS_10is_contextERNS_7contextERPKcS7_RNSt3__15arrayIcLm64EEEmEEvOT0_OT1_OT2_OT3_RT4_
Line
Count
Source
18
3.43k
      {
19
3.43k
         using enum json_type;
20
21
         // Every write below goes through this, and the dump it makes is unchecked: the caller's
22
         // one-shot sizing covers a resizable destination, because minifying only ever removes
23
         // bytes, so the input's length is room enough.
24
         //
25
         // A bounded destination cannot be grown, and asking it for the input's length up front
26
         // refuses a buffer that fits the result -- sizing the output to the minified length is the
27
         // obvious thing to do, and `{ "a" : 1 }` into a 7 byte buffer has to work. So each write
28
         // asks for exactly what it stores instead; see emit_bytes for where that count comes from.
29
         // None of it survives for a resizable destination, which keeps the unchecked dumps and
30
         // nothing more.
31
3.43k
         const auto put = [&](const auto& x) { return emit_bytes<false>(ctx, b, ix, x); };
32
33
3.43k
         auto ws_start = it;
34
3.43k
         uint64_t ws_size{};
35
36
3.43k
         auto skip_expected_whitespace = [&] {
37
3.43k
            auto new_ws_start = it;
38
3.43k
            if (ws_size && std::ptrdiff_t(ws_size) < end - it) [[likely]] {
39
3.43k
               skip_matching_ws(ws_start, it, ws_size);
40
3.43k
            }
41
42
3.43k
            if constexpr (Opts.null_terminated) {
43
3.43k
               while (whitespace_table[uint8_t(*it)]) {
44
3.43k
                  ++it;
45
3.43k
               }
46
3.43k
            }
47
3.43k
            else {
48
3.43k
               while ((it < end) && whitespace_table[uint8_t(*it)]) {
49
3.43k
                  ++it;
50
3.43k
               }
51
3.43k
            }
52
3.43k
            ws_start = new_ws_start;
53
3.43k
            ws_size = size_t(it - new_ws_start);
54
3.43k
         };
55
56
3.43k
         auto skip_whitespace = [&] {
57
3.43k
            if constexpr (Opts.null_terminated) {
58
3.43k
               while (whitespace_table[uint8_t(*it)]) {
59
3.43k
                  ++it;
60
3.43k
               }
61
3.43k
            }
62
3.43k
            else {
63
3.43k
               while ((it < end) && whitespace_table[uint8_t(*it)]) {
64
3.43k
                  ++it;
65
3.43k
               }
66
3.43k
            }
67
3.43k
         };
68
69
3.43k
         skip_whitespace();
70
71
25.1k
         while ([&]() -> bool {
72
25.1k
            if constexpr (Opts.null_terminated) {
73
25.1k
               return true;
74
25.1k
            }
75
25.1k
            else {
76
25.1k
               return it < end;
77
25.1k
            }
78
25.1k
         }()) {
79
24.1k
            switch (json_types[uint8_t(*it)]) {
80
929
            case String: {
81
929
               const auto value = read_json_string(ctx, it, end);
82
929
               if (bool(ctx.error)) [[unlikely]] {
83
97
                  return;
84
97
               }
85
               // non-empty: the scanner reports an empty view as an error
86
832
               if (not put(value)) [[unlikely]] {
87
60
                  return;
88
60
               }
89
772
               skip_whitespace();
90
772
               break;
91
832
            }
92
5.38k
            case Comma: {
93
5.38k
               if (not put(',')) [[unlikely]] {
94
34
                  return;
95
34
               }
96
5.34k
               ++it;
97
5.34k
               skip_expected_whitespace();
98
5.34k
               break;
99
5.38k
            }
100
879
            case Number: {
101
879
               const auto value = read_json_number<Opts.null_terminated>(it, end);
102
               // non-empty: a Number match is one valid character
103
879
               if (not put(value)) [[unlikely]] {
104
32
                  return;
105
32
               }
106
847
               skip_whitespace();
107
847
               break;
108
879
            }
109
1.06k
            case Colon: {
110
1.06k
               if (not put(':')) [[unlikely]] {
111
5
                  return;
112
5
               }
113
1.05k
               ++it;
114
1.05k
               skip_whitespace();
115
1.05k
               break;
116
1.06k
            }
117
4.74k
            case Array_Start: {
118
4.74k
               if (not put('[')) [[unlikely]] {
119
32
                  return;
120
32
               }
121
4.70k
               ++it;
122
4.70k
               skip_expected_whitespace();
123
4.70k
               break;
124
4.74k
            }
125
738
            case Array_End: {
126
738
               if (not put(']')) [[unlikely]] {
127
9
                  return;
128
9
               }
129
729
               ++it;
130
729
               skip_whitespace();
131
729
               break;
132
738
            }
133
409
            case Null: {
134
               // The type table matched on the first byte alone; see match_literal for why writing
135
               // the literal from the writer's own spelling needs the rest of it checked. Stepping
136
               // over it unchecked also puts `it` past `end`, and from there the loop goes on
137
               // minifying whatever follows the document into an output sized for the document.
138
409
               if (not match_literal<"null">(ctx, it, end)) [[unlikely]] {
139
110
                  return;
140
110
               }
141
299
               if (not put("null")) [[unlikely]] {
142
11
                  return;
143
11
               }
144
288
               skip_whitespace();
145
288
               break;
146
299
            }
147
803
            case Bool: {
148
803
               if (*it == 't') {
149
466
                  if (not match_literal<"true">(ctx, it, end)) [[unlikely]] {
150
93
                     return;
151
93
                  }
152
373
                  if (not put("true")) [[unlikely]] {
153
11
                     return;
154
11
                  }
155
362
                  skip_whitespace();
156
362
                  break;
157
373
               }
158
337
               else {
159
337
                  if (not match_literal<"false">(ctx, it, end)) [[unlikely]] {
160
117
                     return;
161
117
                  }
162
220
                  if (not put("false")) [[unlikely]] {
163
11
                     return;
164
11
                  }
165
209
                  skip_whitespace();
166
209
                  break;
167
220
               }
168
803
            }
169
5.12k
            case Object_Start: {
170
5.12k
               if (not put('{')) [[unlikely]] {
171
30
                  return;
172
30
               }
173
5.09k
               ++it;
174
5.09k
               skip_expected_whitespace();
175
5.09k
               break;
176
5.12k
            }
177
867
            case Object_End: {
178
867
               if (not put('}')) [[unlikely]] {
179
8
                  return;
180
8
               }
181
859
               ++it;
182
859
               skip_whitespace();
183
859
               break;
184
867
            }
185
1.60k
            case Comment: {
186
1.60k
               if constexpr (Opts.comments) {
187
1.60k
                  const auto comment = read_jsonc_comment(ctx, it, end);
188
1.60k
                  if (bool(ctx.error)) [[unlikely]] {
189
127
                     return;
190
127
                  }
191
                  // A line comment is dropped rather than written out. Minifying is what removes
192
                  // the newline that ends it, and a line comment with no line break behind it
193
                  // comments out the whole rest of the output.
194
1.47k
                  if (not comment.line) {
195
                     // non-empty: an empty view comes with an error
196
452
                     if (not put(comment.text)) [[unlikely]] {
197
52
                        return;
198
52
                     }
199
452
                  }
200
1.42k
                  skip_whitespace();
201
1.42k
                  break;
202
               }
203
               else {
204
                  [[fallthrough]];
205
               }
206
1.60k
            }
207
3.20k
            [[unlikely]] default: {
208
               // A null terminated run carries no bound in its loop condition, so it ends here, on
209
               // the terminator, which is not a JSON token. Reaching it is the end of the document
210
               // rather than an error -- unclassified is how the type table reports both, and
211
               // without this the minifier left syntax_error behind on every input it was ever
212
               // given, valid or not, which is what made its error not worth returning.
213
               if constexpr (Opts.null_terminated) {
214
                  if (it >= end) {
215
                     return;
216
                  }
217
               }
218
3.20k
               ctx.error = error_code::syntax_error;
219
3.20k
               return;
220
1.60k
            }
221
24.1k
            }
222
24.1k
         }
223
3.43k
      }
224
225
      // Returns the number of bytes written, which is what a bounded output has no other way to
226
      // learn: it has no size to be shrunk to the result the way a resizable one does.
227
      template <auto Opts, class In, output_buffer Out>
228
         requires(contiguous<In> && resizable<In>)
229
      inline size_t minify_json(is_context auto&& ctx, In&& in, Out&& out)
230
26.4k
      {
231
26.4k
         if (in.size() == 0) {
232
0
            return 0;
233
0
         }
234
235
26.4k
         if constexpr (resizable<Out>) {
236
            // Minifying only ever removes bytes, so this is room enough for whatever comes out.
237
            // A bounded output is checked per write instead; see the scan above for why.
238
23.0k
            out.resize(in.size() + 2 * padding_bytes);
239
23.0k
         }
240
26.4k
         size_t ix = 0;
241
26.4k
         auto [it, end] = read_iterators<Opts>(in);
242
26.4k
         if (bool(ctx.error)) [[unlikely]] {
243
0
            return 0;
244
0
         }
245
246
         // The input is no longer grown and shrunk around this: everything the scan below reads
247
         // through -- read_json_string, read_json_number, skip_matching_ws -- bounds its own loads
248
         // against `end`, so there is nothing left for the padding to protect.
249
26.4k
         if constexpr (self_terminating<In>) {
250
12.7k
            minify_json<opt_true<Opts, &opts::null_terminated>>(ctx, it, end, out, ix);
251
         }
252
13.7k
         else {
253
13.7k
            minify_json<opt_false<Opts, &opts::null_terminated>>(ctx, it, end, out, ix);
254
13.7k
         }
255
256
26.4k
         if constexpr (resizable<Out>) {
257
23.0k
            out.resize(ix);
258
23.0k
         }
259
26.4k
         return ix;
260
26.4k
      }
_ZN3glz6detail11minify_jsonITnDaXtlNS_4optsELj10ELb1ELb0ELb1ELb1EEERNSt3__16vectorIcNS3_9allocatorIcEEEETkNS_13output_bufferERNS3_12basic_stringIcNS3_11char_traitsIcEES6_EETkNS_10is_contextERNS_7contextEQaa10contiguousIT0_E9resizableISG_EEEmOT2_OSG_OT1_
Line
Count
Source
230
6.86k
      {
231
6.86k
         if (in.size() == 0) {
232
0
            return 0;
233
0
         }
234
235
6.86k
         if constexpr (resizable<Out>) {
236
            // Minifying only ever removes bytes, so this is room enough for whatever comes out.
237
            // A bounded output is checked per write instead; see the scan above for why.
238
6.86k
            out.resize(in.size() + 2 * padding_bytes);
239
6.86k
         }
240
6.86k
         size_t ix = 0;
241
6.86k
         auto [it, end] = read_iterators<Opts>(in);
242
6.86k
         if (bool(ctx.error)) [[unlikely]] {
243
0
            return 0;
244
0
         }
245
246
         // The input is no longer grown and shrunk around this: everything the scan below reads
247
         // through -- read_json_string, read_json_number, skip_matching_ws -- bounds its own loads
248
         // against `end`, so there is nothing left for the padding to protect.
249
         if constexpr (self_terminating<In>) {
250
            minify_json<opt_true<Opts, &opts::null_terminated>>(ctx, it, end, out, ix);
251
         }
252
6.86k
         else {
253
6.86k
            minify_json<opt_false<Opts, &opts::null_terminated>>(ctx, it, end, out, ix);
254
6.86k
         }
255
256
6.86k
         if constexpr (resizable<Out>) {
257
6.86k
            out.resize(ix);
258
6.86k
         }
259
6.86k
         return ix;
260
6.86k
      }
_ZN3glz6detail11minify_jsonITnDaXtlNS_4optsELj10ELb1ELb1ELb1ELb1EEERNSt3__16vectorIcNS3_9allocatorIcEEEETkNS_13output_bufferERNS3_12basic_stringIcNS3_11char_traitsIcEES6_EETkNS_10is_contextERNS_7contextEQaa10contiguousIT0_E9resizableISG_EEEmOT2_OSG_OT1_
Line
Count
Source
230
3.43k
      {
231
3.43k
         if (in.size() == 0) {
232
0
            return 0;
233
0
         }
234
235
3.43k
         if constexpr (resizable<Out>) {
236
            // Minifying only ever removes bytes, so this is room enough for whatever comes out.
237
            // A bounded output is checked per write instead; see the scan above for why.
238
3.43k
            out.resize(in.size() + 2 * padding_bytes);
239
3.43k
         }
240
3.43k
         size_t ix = 0;
241
3.43k
         auto [it, end] = read_iterators<Opts>(in);
242
3.43k
         if (bool(ctx.error)) [[unlikely]] {
243
0
            return 0;
244
0
         }
245
246
         // The input is no longer grown and shrunk around this: everything the scan below reads
247
         // through -- read_json_string, read_json_number, skip_matching_ws -- bounds its own loads
248
         // against `end`, so there is nothing left for the padding to protect.
249
         if constexpr (self_terminating<In>) {
250
            minify_json<opt_true<Opts, &opts::null_terminated>>(ctx, it, end, out, ix);
251
         }
252
3.43k
         else {
253
3.43k
            minify_json<opt_false<Opts, &opts::null_terminated>>(ctx, it, end, out, ix);
254
3.43k
         }
255
256
3.43k
         if constexpr (resizable<Out>) {
257
3.43k
            out.resize(ix);
258
3.43k
         }
259
3.43k
         return ix;
260
3.43k
      }
_ZN3glz6detail11minify_jsonITnDaXtlNS_4optsELj10ELb1ELb1ELb1ELb1EEERNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEETkNS_13output_bufferESA_TkNS_10is_contextERNS_7contextEQaa10contiguousIT0_E9resizableISD_EEEmOT2_OSD_OT1_
Line
Count
Source
230
12.7k
      {
231
12.7k
         if (in.size() == 0) {
232
0
            return 0;
233
0
         }
234
235
12.7k
         if constexpr (resizable<Out>) {
236
            // Minifying only ever removes bytes, so this is room enough for whatever comes out.
237
            // A bounded output is checked per write instead; see the scan above for why.
238
12.7k
            out.resize(in.size() + 2 * padding_bytes);
239
12.7k
         }
240
12.7k
         size_t ix = 0;
241
12.7k
         auto [it, end] = read_iterators<Opts>(in);
242
12.7k
         if (bool(ctx.error)) [[unlikely]] {
243
0
            return 0;
244
0
         }
245
246
         // The input is no longer grown and shrunk around this: everything the scan below reads
247
         // through -- read_json_string, read_json_number, skip_matching_ws -- bounds its own loads
248
         // against `end`, so there is nothing left for the padding to protect.
249
12.7k
         if constexpr (self_terminating<In>) {
250
12.7k
            minify_json<opt_true<Opts, &opts::null_terminated>>(ctx, it, end, out, ix);
251
         }
252
         else {
253
            minify_json<opt_false<Opts, &opts::null_terminated>>(ctx, it, end, out, ix);
254
         }
255
256
12.7k
         if constexpr (resizable<Out>) {
257
12.7k
            out.resize(ix);
258
12.7k
         }
259
12.7k
         return ix;
260
12.7k
      }
_ZN3glz6detail11minify_jsonITnDaXtlNS_4optsELj10ELb1ELb1ELb1ELb1EEERNSt3__16vectorIcNS3_9allocatorIcEEEETkNS_13output_bufferERNS3_5arrayIcLm64EEETkNS_10is_contextERNS_7contextEQaa10contiguousIT0_E9resizableISE_EEEmOT2_OSE_OT1_
Line
Count
Source
230
3.43k
      {
231
3.43k
         if (in.size() == 0) {
232
0
            return 0;
233
0
         }
234
235
         if constexpr (resizable<Out>) {
236
            // Minifying only ever removes bytes, so this is room enough for whatever comes out.
237
            // A bounded output is checked per write instead; see the scan above for why.
238
            out.resize(in.size() + 2 * padding_bytes);
239
         }
240
3.43k
         size_t ix = 0;
241
3.43k
         auto [it, end] = read_iterators<Opts>(in);
242
3.43k
         if (bool(ctx.error)) [[unlikely]] {
243
0
            return 0;
244
0
         }
245
246
         // The input is no longer grown and shrunk around this: everything the scan below reads
247
         // through -- read_json_string, read_json_number, skip_matching_ws -- bounds its own loads
248
         // against `end`, so there is nothing left for the padding to protect.
249
         if constexpr (self_terminating<In>) {
250
            minify_json<opt_true<Opts, &opts::null_terminated>>(ctx, it, end, out, ix);
251
         }
252
3.43k
         else {
253
3.43k
            minify_json<opt_false<Opts, &opts::null_terminated>>(ctx, it, end, out, ix);
254
3.43k
         }
255
256
         if constexpr (resizable<Out>) {
257
            out.resize(ix);
258
         }
259
3.43k
         return ix;
260
3.43k
      }
261
   }
262
263
   // The overloads that write into a caller's buffer report what went wrong, and how many bytes
264
   // they wrote, which is the only way a bounded output learns where its result ends. That count is
265
   // an offset into the output, not the input, so glz::format_error(ec, source) -- which reads it
266
   // as a position in the buffer it is handed -- does not point at the offending byte here. Not
267
   // [[nodiscard]]:
268
   // minifying auto-generated JSON does not fail, so the callers that have always ignored the
269
   // outcome are right to, and warning at all of them would say nothing useful. The overloads that
270
   // return the text have nowhere to put an error, so they come back empty rather than hand over
271
   // the prefix the scan managed before it stopped -- routinely an unterminated string or an
272
   // unclosed brace, which is not a document but a silent truncation of one.
273
   //
274
   // Minifying reports what it actually parses, which is strings, comments and literals. It does
275
   // not check that the document is structurally valid JSON -- `[1 2]` minifies to `[12]` -- so a
276
   // document that may not be well formed wants glz::validate_json or glz::validate_jsonc.
277
278
   template <auto Opts = opts{}>
279
   inline error_ctx minify_json(resizable auto& in, auto& out)
280
   {
281
      context ctx{};
282
      const auto n = detail::minify_json<Opts>(ctx, in, out);
283
      return {n, ctx.error, ctx.custom_error_message};
284
   }
285
286
   template <auto Opts = opts{}>
287
   inline std::string minify_json(resizable auto& in)
288
6.86k
   {
289
6.86k
      context ctx{};
290
6.86k
      std::string out{};
291
6.86k
      detail::minify_json<Opts>(ctx, in, out);
292
6.86k
      if (bool(ctx.error)) [[unlikely]] {
293
5.81k
         return {}; // an incomplete result is not a document; see above
294
5.81k
      }
295
1.04k
      return out;
296
6.86k
   }
297
298
   template <auto Opts = opts{}>
299
   inline error_ctx minify_jsonc(resizable auto& in, auto& out)
300
12.7k
   {
301
12.7k
      context ctx{};
302
12.7k
      const auto n = detail::minify_json<opt_true<Opts, &opts::comments>>(ctx, in, out);
303
12.7k
      return {n, ctx.error, ctx.custom_error_message};
304
12.7k
   }
_ZN3glz12minify_jsoncITnDaXtlNS_4optsELj10ELb1ELb0ELb1ELb1EEETkNS_9resizableENSt3__16vectorIcNS2_9allocatorIcEEEENS2_5arrayIcLm64EEEEENS_9error_ctxERT0_RT1_
Line
Count
Source
300
3.43k
   {
301
3.43k
      context ctx{};
302
3.43k
      const auto n = detail::minify_json<opt_true<Opts, &opts::comments>>(ctx, in, out);
303
3.43k
      return {n, ctx.error, ctx.custom_error_message};
304
3.43k
   }
_ZN3glz12minify_jsoncITnDaXtlNS_4optsELj10ELb1ELb0ELb1ELb1EEETkNS_9resizableENSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEES8_EENS_9error_ctxERT0_RT1_
Line
Count
Source
300
9.29k
   {
301
9.29k
      context ctx{};
302
9.29k
      const auto n = detail::minify_json<opt_true<Opts, &opts::comments>>(ctx, in, out);
303
9.29k
      return {n, ctx.error, ctx.custom_error_message};
304
9.29k
   }
305
306
   template <auto Opts = opts{}>
307
   inline std::string minify_jsonc(resizable auto& in)
308
6.86k
   {
309
6.86k
      context ctx{};
310
6.86k
      std::string out{};
311
6.86k
      detail::minify_json<opt_true<Opts, &opts::comments>>(ctx, in, out);
312
6.86k
      if (bool(ctx.error)) [[unlikely]] {
313
4.56k
         return {}; // an incomplete result is not a document; see above
314
4.56k
      }
315
2.29k
      return out;
316
6.86k
   }
_ZN3glz12minify_jsoncITnDaXtlNS_4optsELj10ELb1ELb0ELb1ELb1EEETkNS_9resizableENSt3__16vectorIcNS2_9allocatorIcEEEEEENS2_12basic_stringIcNS2_11char_traitsIcEES5_EERT0_
Line
Count
Source
308
3.43k
   {
309
3.43k
      context ctx{};
310
3.43k
      std::string out{};
311
3.43k
      detail::minify_json<opt_true<Opts, &opts::comments>>(ctx, in, out);
312
3.43k
      if (bool(ctx.error)) [[unlikely]] {
313
2.28k
         return {}; // an incomplete result is not a document; see above
314
2.28k
      }
315
1.14k
      return out;
316
3.43k
   }
_ZN3glz12minify_jsoncITnDaXtlNS_4optsELj10ELb1ELb0ELb1ELb1EEETkNS_9resizableENSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEEES8_RT0_
Line
Count
Source
308
3.43k
   {
309
3.43k
      context ctx{};
310
3.43k
      std::string out{};
311
3.43k
      detail::minify_json<opt_true<Opts, &opts::comments>>(ctx, in, out);
312
3.43k
      if (bool(ctx.error)) [[unlikely]] {
313
2.28k
         return {}; // an incomplete result is not a document; see above
314
2.28k
      }
315
1.14k
      return out;
316
3.43k
   }
317
}