Files
json/docs/mkdocs/docs/api/basic_json/dump.md
T
Niels Lohmann bfa4886f0f Write doubles with the shortest digits (Żmij), digits in registers
Write doubles with the conversion of Zmij by Victor Zverovich (MIT),
ported to C++11 (detail/conversions/zmij.hpp). It finds the
shortest decimal that reads back as the same double, and the
closest one if there are several. Grisu2, used until now, is fast
but not always shortest: it sometimes writes a 17th digit where 16
suffice, or a last digit that is not the closest. The layout is
unchanged (1.5, 100.0, 1e+100, -0.0); float keeps Grisu2.

Digits are converted eight at a time with the BCD conversion of
Xiang JunBo, as in Zmij, and written with one byte swap per eight
digits and fixed-size moves instead of per-digit loops. Leading and
trailing zeros are counted from those bytes. to_chars() uses a
local buffer when the caller's is shorter than the 41 bytes this
may write. The powers of ten come from the number-parsing table,
adjusted where it holds values rounded up, and extended with Zmij's
compressed tables beyond 10^308.

write_shortest() converts its 16 digits in one vector register
(SSE2 on x86-64, NEON on 64-bit Arm, both baseline) and inserts the
decimal point inside the register, avoiding a store-forwarding
stall that cost about 25% of the time to write a double. dump()
writes floats and integers straight into the serializer's write
buffer instead of copying them from a member buffer, and small
integers eight digits at a time. read_eight_bytes() and
parse_eight_digits() are marked always-inline, which GCC had been
calling out of line in the number-parsing loops.

Of one million random doubles, about 0.14% are now written with
different digits, always to a value that still reads back as the
same double.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-07 16:41:47 +02:00

4.2 KiB

nlohmann::basic_json::dump

string_t dump(const int indent = -1,
              const char indent_char = ' ',
              const bool ensure_ascii = false,
              const error_handler_t error_handler = error_handler_t::strict) const;

Serialization function for JSON values. The function tries to mimic Python's json.dumps() function, and currently supports its indent and ensure_ascii parameters.

Parameters

indent (in)
If indent is nonnegative, then array elements and object members will be pretty-printed with that indent level. An indent level of 0 will only insert newlines. -1 (the default) selects the most compact representation.
indent_char (in)
The character to use for indentation if indent is greater than 0. The default is (space).
ensure_ascii (in)
If ensure_ascii is true, all non-ASCII characters in the output are escaped with \uXXXX sequences, and the result consists of ASCII characters only.
error_handler (in)
how to react on decoding errors; there are four possible values (see error_handler_t: strict (throws an exception in case a decoding error occurs; default), replace (replace invalid UTF-8 sequences with U+FFFD), ignore (ignore invalid UTF-8 sequences during serialization; all valid bytes are copied to the output unchanged, and invalid bytes are dropped), and keep (write the ill-formed bytes to the output as is, without escaping them, even if ensure_ascii is #!cpp true; the result is then not valid UTF-8, but equals the input bytes exactly, and well-formed characters around the ill-formed bytes are still escaped as usual)).

Return value

string containing the serialization of the JSON value

Exception safety

Strong guarantee: if an exception is thrown, there are no changes to any JSON value.

Exceptions

Throws type_error.316 if a string stored inside the JSON value is not UTF-8 encoded and error_handler is set to strict

!!! warning "Serializing untrusted input"

When serializing values that may contain invalid or untrusted UTF-8 (e.g., bytes taken directly from network
input), `dump()` throws [`type_error.316`](../../home/exceptions.md#jsonexceptiontype_error316) in the default
`strict` mode. To serialize such data without throwing, pass
[`error_handler_t::replace`](error_handler_t.md) (substitutes U+FFFD) or
[`error_handler_t::ignore`](error_handler_t.md). Callers that serialize untrusted input on a crash-sensitive path
should either choose a non-strict error handler or wrap `dump()` in a `#!cpp try`/`#!cpp catch`.

See the [FAQ](../../home/faq.md#serializing-untrusted-or-invalid-utf-8) for details.

Complexity

Linear.

Notes

Floating-point numbers are written with the fewest digits that read back as the same value (for #!cpp double; see number handling).

Binary values are serialized as an object containing two keys:

  • "bytes": an array of bytes as integers
  • "subtype": the subtype as integer or #!json null if the binary has no subtype

Examples

??? example

The following example shows the effect of different `indent`, `indent_char`, and `ensure_ascii` parameters to the
result of the serialization.

```cpp
--8<-- "examples/dump.cpp"
```

Output:

```json
--8<-- "examples/dump.output"
```

See also

Version history

  • Added in version 1.0.0.
  • Indentation character indent_char, option ensure_ascii and exceptions added in version 3.0.0.
  • Error handlers added in version 3.4.0.
  • Serialization of binary values added in version 3.8.0.
  • Error handler keep added in version 3.13.0.
  • Doubles are written with the shortest digits (Żmij instead of Grisu2) since version 3.13.0; about 0.1% of doubles are written differently, most of them with fewer digits.