Files
json/api/basic_json_view/number_token.md
T
2026-11-12 11:46:38 +00:00

4.8 KiB

nlohmann::basic_json_view::number_token

string_view_t number_token() const;

Returns the number exactly as it appears in the source text, without parsing or rounding it.

Return value

The number's token text, as a string_view_t into the document's source() text — for example #!cpp "1.50", #!cpp "1E2", #!cpp "-0", or an integer literal with more digits than any number type holds (such as a 30-digit integer, which get<T>() and materialize() can only represent approximately, as a number_float_t).

Exception safety

Strong guarantee: there are no changes to the view or the document it refers to.

Exceptions

Throws type_error.302 if the value is not a number; example: "type must be number, but is string".

As for BasicJsonType, with JSON_DIAGNOSTICS the exception names the JSON Pointer path of the value within the document, and with JSON_DIAGNOSTIC_POSITIONS its bytes in the source text (when materialize() sets them).

Complexity

Constant.

Notes

BasicJsonType has no counterpart to this function: once a number is parsed into number_integer_t, number_unsigned_t, or number_float_t, its original textual form (leading zeros aside, which are already rejected by the grammar; trailing zeros in the fraction; the case and sign of the exponent; ...) is gone. number_token() is useful precisely where that form must survive — a price or an identifier that must be reproduced exactly, or a number too large for any of BasicJsonType's number types to hold without loss.

The returned string_view_t points into the document's source() text or, for a number written by an edit, into storage owned by the document (the token of an edited NaN is nan). It is valid exactly as long as that text or storage is, see the validity rules of basic_json_view. Numbers are never decoded into the document's separate string buffer.

For the same reason, the token must not be passed to read() of the document it came from if that document owns its text or the number was written by an edit: read() releases both before it parses.

Examples

??? example

The example below keeps a price and an order ID exactly as they were written in an incoming order, where
converting them with [`get<T>()`](get.md) would lose information: the price picks up floating-point rounding, and
the order ID — more digits than a 64-bit integer holds — can only be approximated as a `#!cpp double` once
`#!cpp materialize()`d.

```cpp
#include <iostream>
#include <nlohmann/json_view.hpp>

using nlohmann::json_document;
using nlohmann::json_view;

int main()
{
    // a price and an order id from an incoming order -- both need to be
    // reproduced exactly, e.g. for an invoice or an audit log
    json_document doc = json_document::parse(R"(
      {"price": 19.90, "order_id": 1234567890123456789012345, "quantity": 3}
    )");
    const json_view order = doc.root();

    // number_token() returns the number exactly as written in the source
    std::cout << order["price"].number_token() << '\n';
    std::cout << order["order_id"].number_token() << '\n';

    // get<double>() converts it instead -- the exact source text is gone:
    // "19.90" becomes the double closest to 19.9, printed without the
    // trailing zero, and the 25-digit order id -- far beyond any 64-bit
    // integer -- can only be approximated as a double
    std::cout << order["price"].get<double>() << '\n';
    std::cout << order.materialize()["order_id"].dump() << '\n';

    // an ordinary quantity has nothing to lose either way
    std::cout << order["quantity"].number_token() << " == " << order["quantity"].get<int>() << '\n';
}

```

Output:

```json
19.90
1234567890123456789012345
19.9
1.2345678901234568e+24
3 == 3

```

See also

Version history

  • Added in version 3.13.0.