Detect with "JSON for Modern C++" library that integer doesn't fit into a specified type?

The only way to do what you want is to actually retrieve the value in a larger integer type, and then check if the value is within the range of int.

using integer_t = nlohmann::json::number_integer_t;
auto ivalue = json.at("val").get<integer_t>();

if (ivalue < std::numeric_limits<int>::min() || ivalue > std::numeric_limits<int>::max()) {
    // Range error... 
}

Some details...

The number is parsed during the call to parse() using std::strtoull or std::strtoll (depending on the presence of a - sign), and converted to a nlohmann::json::number_integer_t (int64_t1) or nlohmann::json::number_unsigned_t (uint64_t1).

When you query the value with get<int>, the only thing done is a cast from the stored int64_t/uint64_t value to int, so there is no way to check the range at this point.

Also, you cannot retrieve the original "string" since only the actual (unsigned) integer value is stored.

1 int64_t and uint64_t are the default types since nlohmann::json is actually an alias to a basic_json template (much like std::string), but you can use whatever types you want.


Aside Holt's answer, you can also take advantage of the operator== the library defines, which states:

Integer and floating-point numbers are automatically converted before comparison. Note than two NaN values are always treated as unequal.

What happens here is that the number overflows, which means json["val"] != json["val"].get<int>().Disclaimer: I have no idea how efficient this approach is compared to Holt's approach

#include <iostream>
#include <nlohmann/json.hpp>

int main()
{
    auto jsonText = "{ \"val\" : 4294967296 }";
    auto json = nlohmann::json::parse(jsonText);
    auto val = json["val"].get<long long>();
    auto i = json["val"].get<int>();
    bool longOverflow = json["val"] != val;
    bool intOverflow = json["val"] != i;
    std::cout << std::boolalpha << "Long: " << longOverflow << "\nInt: " << intOverflow;
}

Prints:

Long: false
Int: true

Try it online

Note that this has a caveat: If the value stored in the JSON is a double or a float, and is retrieved as a long or int, it'll naturally evaluate to true (12.3 != 12), but it doesn't have to imply an overflow. You can check the general type with is_number_integer() (checks for int, long, and various other types, unsigned or signed) and is_number_float() (checks for double/float).

From what I can tell though, from int/long to double doesn't fail. However, provided a big enough number, the library will fail to parse the number (json.exception.out_of_range.406), so there's a hard limit imposed by the library. From what I can tell, that limit is set at 1.79769e+308 (at least on Wandbox), or the max double value. This also makes double the only type you can't overflow with the library.

As far as automatically checking for number overflow when you retrieve it with a certain type, that's not supported out of the box.