Merge branch 'develop' of https://github.com/nlohmann/json into issue2863

 Conflicts:
	.github/workflows/windows.yml
pull/2908/head
Niels Lohmann 2021-08-14 11:19:48 +02:00
commit 0a0eb7a850
No known key found for this signature in database
GPG Key ID: 7F3CEA63AE251B69
23 changed files with 735 additions and 19 deletions

View File

@ -37,13 +37,13 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: cmake
run: cmake -S . -B build -G "Visual Studio 15 2017" -A ${{ matrix.architecture }} -DJSON_BuildTests=On -DCMAKE_EXE_LINKER_FLAGS="/STACK:4000000"
run: cmake -S . -B build -G "Visual Studio 15 2017" -A ${{ matrix.architecture }} -DJSON_BuildTests=On -DCMAKE_EXE_LINKER_FLAGS="/STACK:4000000" -DCMAKE_CXX_FLAGS="/W4 /WX"
if: matrix.build_type == 'Release' && matrix.architecture == 'x64'
- name: cmake
run: cmake -S . -B build -G "Visual Studio 15 2017" -A ${{ matrix.architecture }} -DJSON_BuildTests=On
run: cmake -S . -B build -G "Visual Studio 15 2017" -A ${{ matrix.architecture }} -DJSON_BuildTests=On -DCMAKE_CXX_FLAGS="/W4 /WX"
if: matrix.build_type == 'Release' && matrix.architecture != 'x64'
- name: cmake
run: cmake -S . -B build -G "Visual Studio 15 2017" -A ${{ matrix.architecture }} -DJSON_BuildTests=On -DJSON_FastTests=ON -DCMAKE_EXE_LINKER_FLAGS="/STACK:4000000"
run: cmake -S . -B build -G "Visual Studio 15 2017" -A ${{ matrix.architecture }} -DJSON_BuildTests=On -DJSON_FastTests=ON -DCMAKE_EXE_LINKER_FLAGS="/STACK:4000000" -DCMAKE_CXX_FLAGS="/W4 /WX"
if: matrix.build_type == 'Debug'
- name: build
run: cmake --build build --config ${{ matrix.build_type }} --parallel 10
@ -56,7 +56,7 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: cmake
run: cmake -S . -B build -G "Visual Studio 15 2017" -DJSON_BuildTests=On -DCMAKE_CXX_FLAGS="/permissive- /std:c++latest /utf-8 /W4"
run: cmake -S . -B build -G "Visual Studio 15 2017" -DJSON_BuildTests=On -DCMAKE_CXX_FLAGS="/permissive- /std:c++latest /utf-8 /W4 /WX"
- name: build
run: cmake --build build --config Release --parallel 10
- name: test
@ -72,10 +72,10 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: cmake
run: cmake -S . -B build -G "Visual Studio 16 2019" -A ${{ matrix.architecture }} -DJSON_BuildTests=On
run: cmake -S . -B build -G "Visual Studio 16 2019" -A ${{ matrix.architecture }} -DJSON_BuildTests=On -DCMAKE_CXX_FLAGS="/W4 /WX"
if: matrix.build_type == 'Release'
- name: cmake
run: cmake -S . -B build -G "Visual Studio 16 2019" -A ${{ matrix.architecture }} -DJSON_BuildTests=On -DJSON_FastTests=ON -DCMAKE_EXE_LINKER_FLAGS="/STACK:4000000"
run: cmake -S . -B build -G "Visual Studio 16 2019" -A ${{ matrix.architecture }} -DJSON_BuildTests=On -DJSON_FastTests=ON -DCMAKE_EXE_LINKER_FLAGS="/STACK:4000000" -DCMAKE_CXX_FLAGS="/W4 /WX"
if: matrix.build_type == 'Debug'
- name: build
run: cmake --build build --config ${{ matrix.build_type }} --parallel 10
@ -88,7 +88,7 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: cmake
run: cmake -S . -B build -G "Visual Studio 16 2019" -DJSON_BuildTests=On -DCMAKE_CXX_FLAGS="/permissive- /std:c++latest /utf-8 /W4" -DCMAKE_EXE_LINKER_FLAGS="/STACK:4000000"
run: cmake -S . -B build -G "Visual Studio 16 2019" -DJSON_BuildTests=On -DCMAKE_CXX_FLAGS="/permissive- /std:c++latest /utf-8 /W4 /WX" -DCMAKE_EXE_LINKER_FLAGS="/STACK:4000000"
- name: build
run: cmake --build build --config Release --parallel 10
- name: test

View File

@ -1649,7 +1649,7 @@ Here is a related issue [#1924](https://github.com/nlohmann/json/issues/1924).
- The code contains numerous debug **assertions** which can be switched off by defining the preprocessor macro `NDEBUG`, see the [documentation of `assert`](https://en.cppreference.com/w/cpp/error/assert). In particular, note [`operator[]`](https://nlohmann.github.io/json/api/basic_json/operator%5B%5D/) implements **unchecked access** for const objects: If the given key is not present, the behavior is undefined (think of a dereferenced null pointer) and yields an [assertion failure](https://github.com/nlohmann/json/issues/289) if assertions are switched on. If you are not sure whether an element in an object exists, use checked access with the [`at()` function](https://nlohmann.github.io/json/api/basic_json/at/). Furthermore, you can define `JSON_ASSERT(x)` to replace calls to `assert(x)`.
- As the exact type of a number is not defined in the [JSON specification](https://tools.ietf.org/html/rfc8259.html), this library tries to choose the best fitting C++ number type automatically. As a result, the type `double` may be used to store numbers which may yield [**floating-point exceptions**](https://github.com/nlohmann/json/issues/181) in certain rare situations if floating-point exceptions have been unmasked in the calling code. These exceptions are not caused by the library and need to be fixed in the calling code, such as by re-masking the exceptions prior to calling library functions.
- The code can be compiled without C++ **runtime type identification** features; that is, you can use the `-fno-rtti` compiler flag.
- **Exceptions** are used widely within the library. They can, however, be switched off with either using the compiler flag `-fno-exceptions` or by defining the symbol `JSON_NOEXCEPTION`. In this case, exceptions are replaced by `abort()` calls. You can further control this behavior by defining `JSON_THROW_USER` (overriding `throw`), `JSON_TRY_USER` (overriding `try`), and `JSON_CATCH_USER` (overriding `catch`). Note that `JSON_THROW_USER` should leave the current scope (e.g., by throwing or aborting), as continuing after it may yield undefined behavior.
- **Exceptions** are used widely within the library. They can, however, be switched off with either using the compiler flag `-fno-exceptions` or by defining the symbol `JSON_NOEXCEPTION`. In this case, exceptions are replaced by `abort()` calls. You can further control this behavior by defining `JSON_THROW_USER` (overriding `throw`), `JSON_TRY_USER` (overriding `try`), and `JSON_CATCH_USER` (overriding `catch`). Note that `JSON_THROW_USER` should leave the current scope (e.g., by throwing or aborting), as continuing after it may yield undefined behavior. Note the explanatory [`what()`](https://en.cppreference.com/w/cpp/error/exception/what) string of exceptions is not available for MSVC if exceptions are disabled, see [#2824](https://github.com/nlohmann/json/discussions/2824).
## Execute unit tests

View File

@ -5,7 +5,7 @@ environment:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
configuration: Debug
platform: x86
CXX_FLAGS: ""
CXX_FLAGS: "/W4 /WX"
LINKER_FLAGS: ""
CMAKE_OPTIONS: ""
GENERATOR: Visual Studio 14 2015
@ -13,7 +13,7 @@ environment:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
configuration: Release
platform: x86
CXX_FLAGS: ""
CXX_FLAGS: "/W4 /WX"
LINKER_FLAGS: ""
CMAKE_OPTIONS: ""
GENERATOR: Visual Studio 14 2015
@ -22,7 +22,7 @@ environment:
configuration: Release
platform: x86
name: with_win_header
CXX_FLAGS: ""
CXX_FLAGS: "/W4 /WX"
LINKER_FLAGS: ""
CMAKE_OPTIONS: ""
GENERATOR: Visual Studio 14 2015
@ -30,7 +30,7 @@ environment:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
configuration: Release
platform: x86
CXX_FLAGS: "/permissive- /std:c++latest /utf-8"
CXX_FLAGS: "/permissive- /std:c++latest /utf-8 /W4 /WX"
LINKER_FLAGS: ""
CMAKE_OPTIONS: ""
GENERATOR: Visual Studio 15 2017
@ -38,7 +38,7 @@ environment:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
configuration: Release
platform: x86
CXX_FLAGS: ""
CXX_FLAGS: "/W4 /WX"
LINKER_FLAGS: ""
CMAKE_OPTIONS: "-DJSON_ImplicitConversions=OFF"
GENERATOR: Visual Studio 16 2019
@ -46,7 +46,7 @@ environment:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
configuration: Release
platform: x64
CXX_FLAGS: ""
CXX_FLAGS: "/W4 /WX"
LINKER_FLAGS: ""
CMAKE_OPTIONS: ""
GENERATOR: Visual Studio 14 2015
@ -54,7 +54,7 @@ environment:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
configuration: Release
platform: x64
CXX_FLAGS: "/permissive- /std:c++latest /Zc:__cplusplus /utf-8 /F4000000"
CXX_FLAGS: "/permissive- /std:c++latest /Zc:__cplusplus /utf-8 /F4000000 /W4 /WX"
LINKER_FLAGS: "/STACK:4000000"
CMAKE_OPTIONS: ""
GENERATOR: Visual Studio 15 2017

View File

@ -99,7 +99,7 @@ set(CLANG_CXXFLAGS "-std=c++11 \
-Wno-extra-semi-stmt \
-Wno-padded \
-Wno-range-loop-analysis \
-Wno-switch-enum -Wno-covered-switch-default \
-Wno-covered-switch-default \
-Wno-weak-vtables \
")
@ -326,7 +326,7 @@ set(GCC_CXXFLAGS "-std=c++11 \
-Wswitch \
-Wswitch-bool \
-Wswitch-default \
-Wno-switch-enum \
-Wswitch-enum \
-Wswitch-outside-range \
-Wswitch-unreachable \
-Wsync-nand \

View File

@ -32,6 +32,8 @@ When defining `JSON_NOEXCEPTION`, `#!cpp try` is replaced by `#!cpp if (true)`,
The same effect is achieved by setting the compiler flag `-fno-exceptions`.
Note the explanatory [`what()`](https://en.cppreference.com/w/cpp/error/exception/what) string of exceptions is not available for MSVC if exceptions are disabled, see [#2824](https://github.com/nlohmann/json/discussions/2824).
## `JSON_NO_IO`
When defined, headers `<cstdio>`, `<ios>`, `<iosfwd>`, `<istream>`, and `<ostream>` are not included and parse functions relying on these headers are excluded. This is relevant for environment where these I/O functions are disallowed for security reasons (e.g., Intel Software Guard Extensions (SGX)).

View File

@ -50,6 +50,8 @@ Note that `JSON_THROW_USER` should leave the current scope (e.g., by throwing or
#include <nlohmann/json.hpp>
```
Note the explanatory [`what()`](https://en.cppreference.com/w/cpp/error/exception/what) string of exceptions is not available for MSVC if exceptions are disabled, see [#2824](https://github.com/nlohmann/json/discussions/2824).
### Extended diagnostic messages
Exceptions in the library are thrown in the local context of the JSON value they are detected. This makes detailed diagnostics messages, and hence debugging, difficult.

View File

@ -58,6 +58,13 @@ void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
break;
}
case value_t::null:
case value_t::object:
case value_t::array:
case value_t::string:
case value_t::boolean:
case value_t::binary:
case value_t::discarded:
default:
JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
}
@ -343,6 +350,12 @@ void from_json(const BasicJsonType& j, ArithmeticType& val)
break;
}
case value_t::null:
case value_t::object:
case value_t::array:
case value_t::string:
case value_t::binary:
case value_t::discarded:
default:
JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
}

View File

@ -1066,8 +1066,10 @@ char* to_chars(char* first, const char* last, FloatType value)
*first++ = '-';
}
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
if (value == 0) // +-0
{
*first++ = '0';
@ -1076,7 +1078,9 @@ char* to_chars(char* first, const char* last, FloatType value)
*first++ = '0';
return first;
}
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);

View File

@ -102,6 +102,14 @@ class exception : public std::exception
break;
}
case value_t::null: // LCOV_EXCL_LINE
case value_t::string: // LCOV_EXCL_LINE
case value_t::boolean: // LCOV_EXCL_LINE
case value_t::number_integer: // LCOV_EXCL_LINE
case value_t::number_unsigned: // LCOV_EXCL_LINE
case value_t::number_float: // LCOV_EXCL_LINE
case value_t::binary: // LCOV_EXCL_LINE
case value_t::discarded: // LCOV_EXCL_LINE
default: // LCOV_EXCL_LINE
break; // LCOV_EXCL_LINE
}

View File

@ -120,6 +120,7 @@ class binary_reader
result = parse_ubjson_internal();
break;
case input_format_t::json: // LCOV_EXCL_LINE
default: // LCOV_EXCL_LINE
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
}
@ -2279,6 +2280,20 @@ class binary_reader
return sax->number_unsigned(number_lexer.get_number_unsigned());
case token_type::value_float:
return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
case token_type::uninitialized:
case token_type::literal_true:
case token_type::literal_false:
case token_type::literal_null:
case token_type::value_string:
case token_type::begin_array:
case token_type::begin_object:
case token_type::end_array:
case token_type::end_object:
case token_type::name_separator:
case token_type::value_separator:
case token_type::parse_error:
case token_type::end_of_input:
case token_type::literal_or_value:
default:
return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number"), BasicJsonType()));
}
@ -2481,6 +2496,7 @@ class binary_reader
error_msg += "BSON";
break;
case input_format_t::json: // LCOV_EXCL_LINE
default: // LCOV_EXCL_LINE
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
}

View File

@ -334,6 +334,13 @@ class parser
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), BasicJsonType()));
}
case token_type::uninitialized:
case token_type::end_array:
case token_type::end_object:
case token_type::name_separator:
case token_type::value_separator:
case token_type::end_of_input:
case token_type::literal_or_value:
default: // the last token was unexpected
{
return sax->parse_error(m_lexer.get_position(),

View File

@ -104,6 +104,14 @@ class iter_impl
break;
}
case value_t::null:
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
{
m_it.primitive_iterator = primitive_iterator_t();
@ -200,6 +208,13 @@ class iter_impl
break;
}
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
{
m_it.primitive_iterator.set_begin();
@ -230,6 +245,14 @@ class iter_impl
break;
}
case value_t::null:
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
{
m_it.primitive_iterator.set_end();
@ -264,6 +287,13 @@ class iter_impl
case value_t::null:
JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
{
if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
@ -298,6 +328,14 @@ class iter_impl
return &*m_it.array_iterator;
}
case value_t::null:
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
{
if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
@ -343,6 +381,14 @@ class iter_impl
break;
}
case value_t::null:
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
{
++m_it.primitive_iterator;
@ -386,6 +432,14 @@ class iter_impl
break;
}
case value_t::null:
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
{
--m_it.primitive_iterator;
@ -419,6 +473,14 @@ class iter_impl
case value_t::array:
return (m_it.array_iterator == other.m_it.array_iterator);
case value_t::null:
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
return (m_it.primitive_iterator == other.m_it.primitive_iterator);
}
@ -456,6 +518,14 @@ class iter_impl
case value_t::array:
return (m_it.array_iterator < other.m_it.array_iterator);
case value_t::null:
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
return (m_it.primitive_iterator < other.m_it.primitive_iterator);
}
@ -507,6 +577,14 @@ class iter_impl
break;
}
case value_t::null:
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
{
m_it.primitive_iterator += i;
@ -575,6 +653,14 @@ class iter_impl
case value_t::array:
return m_it.array_iterator - other.m_it.array_iterator;
case value_t::null:
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
return m_it.primitive_iterator - other.m_it.primitive_iterator;
}
@ -599,6 +685,13 @@ class iter_impl
case value_t::null:
JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
{
if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))

View File

@ -97,6 +97,14 @@ template<typename IteratorType> class iteration_proxy_value
return anchor.key();
// use an empty key for all primitive types
case value_t::null:
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
return empty_str;
}

View File

@ -441,6 +441,13 @@ class json_pointer
an error situation, because primitive values may only occur as
single value; that is, with an empty list of reference tokens.
*/
case detail::value_t::string:
case detail::value_t::boolean:
case detail::value_t::number_integer:
case detail::value_t::number_unsigned:
case detail::value_t::number_float:
case detail::value_t::binary:
case detail::value_t::discarded:
default:
JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", j));
}
@ -513,6 +520,14 @@ class json_pointer
break;
}
case detail::value_t::null:
case detail::value_t::string:
case detail::value_t::boolean:
case detail::value_t::number_integer:
case detail::value_t::number_unsigned:
case detail::value_t::number_float:
case detail::value_t::binary:
case detail::value_t::discarded:
default:
JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
}
@ -555,6 +570,14 @@ class json_pointer
break;
}
case detail::value_t::null:
case detail::value_t::string:
case detail::value_t::boolean:
case detail::value_t::number_integer:
case detail::value_t::number_unsigned:
case detail::value_t::number_float:
case detail::value_t::binary:
case detail::value_t::discarded:
default:
JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
}
@ -602,6 +625,14 @@ class json_pointer
break;
}
case detail::value_t::null:
case detail::value_t::string:
case detail::value_t::boolean:
case detail::value_t::number_integer:
case detail::value_t::number_unsigned:
case detail::value_t::number_float:
case detail::value_t::binary:
case detail::value_t::discarded:
default:
JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
}
@ -644,6 +675,14 @@ class json_pointer
break;
}
case detail::value_t::null:
case detail::value_t::string:
case detail::value_t::boolean:
case detail::value_t::number_integer:
case detail::value_t::number_unsigned:
case detail::value_t::number_float:
case detail::value_t::binary:
case detail::value_t::discarded:
default:
JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
}
@ -714,6 +753,14 @@ class json_pointer
break;
}
case detail::value_t::null:
case detail::value_t::string:
case detail::value_t::boolean:
case detail::value_t::number_integer:
case detail::value_t::number_unsigned:
case detail::value_t::number_float:
case detail::value_t::binary:
case detail::value_t::discarded:
default:
{
// we do not expect primitive values if there is still a
@ -847,6 +894,14 @@ class json_pointer
break;
}
case detail::value_t::null:
case detail::value_t::string:
case detail::value_t::boolean:
case detail::value_t::number_integer:
case detail::value_t::number_unsigned:
case detail::value_t::number_float:
case detail::value_t::binary:
case detail::value_t::discarded:
default:
{
// add primitive value with its reference string

View File

@ -56,6 +56,15 @@ class binary_writer
break;
}
case value_t::null:
case value_t::array:
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
{
JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name()), j));;
@ -381,6 +390,7 @@ class binary_writer
break;
}
case value_t::discarded:
default:
break;
}
@ -702,6 +712,7 @@ class binary_writer
break;
}
case value_t::discarded:
default:
break;
}
@ -906,6 +917,7 @@ class binary_writer
break;
}
case value_t::discarded:
default:
break;
}
@ -926,6 +938,7 @@ class binary_writer
if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
{
JSON_THROW(out_of_range::create(409, "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")", j));
static_cast<void>(j);
}
return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
@ -1157,6 +1170,7 @@ class binary_writer
return header_size + 0ul;
// LCOV_EXCL_START
case value_t::discarded:
default:
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
return 0ul;
@ -1203,6 +1217,7 @@ class binary_writer
return write_bson_null(name);
// LCOV_EXCL_START
case value_t::discarded:
default:
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
return;
@ -1493,6 +1508,7 @@ class binary_writer
case value_t::object:
return '{';
case value_t::discarded:
default: // discarded values
return 'N';
}
@ -1542,8 +1558,10 @@ class binary_writer
void write_compact_float(const number_float_t n, detail::input_format_t format)
{
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
@ -1560,7 +1578,9 @@ class binary_writer
: get_msgpack_float_prefix(n));
write_number(n);
}
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
}
public:

View File

@ -1059,6 +1059,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
break;
}
case value_t::discarded:
default:
{
object = nullptr; // silence warning, see #821
@ -1216,6 +1217,12 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
break;
}
case value_t::null:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::discarded:
default:
{
break;
@ -1287,6 +1294,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
break;
}
case value_t::null:
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
break;
}
@ -2051,6 +2066,11 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
break;
}
case value_t::null:
case value_t::object:
case value_t::array:
case value_t::binary:
case value_t::discarded:
default:
break;
}
@ -2107,6 +2127,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
break;
}
case value_t::null:
case value_t::discarded:
default:
JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " + std::string(first.m_object->type_name()), *first.m_object));
}
@ -2206,6 +2228,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
break;
}
case value_t::null:
case value_t::discarded:
default:
break;
}
@ -4230,6 +4254,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
break;
}
case value_t::null:
case value_t::discarded:
default:
JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
}
@ -4346,6 +4372,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
break;
}
case value_t::null:
case value_t::discarded:
default:
JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
}
@ -5101,6 +5129,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
return m_value.object->empty();
}
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
{
// all other types are nonempty
@ -5174,6 +5209,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
return m_value.object->size();
}
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
{
// all other types have size 1
@ -5239,6 +5281,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
return m_value.object->max_size();
}
case value_t::null:
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
{
// all other types have max_size() == size()
@ -5346,6 +5396,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
break;
}
case value_t::null:
case value_t::discarded:
default:
break;
}
@ -6278,8 +6330,10 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
*/
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
{
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
const auto lhs_type = lhs.type();
const auto rhs_type = rhs.type();
@ -6314,6 +6368,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
case value_t::binary:
return *lhs.m_value.binary == *rhs.m_value.binary;
case value_t::discarded:
default:
return false;
}
@ -6344,7 +6399,9 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
}
return false;
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
}
/*!
@ -6478,6 +6535,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
case value_t::binary:
return (*lhs.m_value.binary) < (*rhs.m_value.binary);
case value_t::discarded:
default:
return false;
}
@ -7102,6 +7160,9 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
return "binary";
case value_t::discarded:
return "discarded";
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
default:
return "number";
}
@ -8439,6 +8500,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
}
// if there exists a parent it cannot be primitive
case value_t::string: // LCOV_EXCL_LINE
case value_t::boolean: // LCOV_EXCL_LINE
case value_t::number_integer: // LCOV_EXCL_LINE
case value_t::number_unsigned: // LCOV_EXCL_LINE
case value_t::number_float: // LCOV_EXCL_LINE
case value_t::binary: // LCOV_EXCL_LINE
case value_t::discarded: // LCOV_EXCL_LINE
default: // LCOV_EXCL_LINE
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
}
@ -8598,6 +8666,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
break;
}
case patch_operations::invalid:
default:
{
// op must be "add", "remove", "replace", "move", "copy", or
@ -8754,6 +8823,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
break;
}
case value_t::null:
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
{
// both primitive type: replace value

View File

@ -2697,6 +2697,14 @@ class exception : public std::exception
break;
}
case value_t::null: // LCOV_EXCL_LINE
case value_t::string: // LCOV_EXCL_LINE
case value_t::boolean: // LCOV_EXCL_LINE
case value_t::number_integer: // LCOV_EXCL_LINE
case value_t::number_unsigned: // LCOV_EXCL_LINE
case value_t::number_float: // LCOV_EXCL_LINE
case value_t::binary: // LCOV_EXCL_LINE
case value_t::discarded: // LCOV_EXCL_LINE
default: // LCOV_EXCL_LINE
break; // LCOV_EXCL_LINE
}
@ -3894,6 +3902,13 @@ void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
break;
}
case value_t::null:
case value_t::object:
case value_t::array:
case value_t::string:
case value_t::boolean:
case value_t::binary:
case value_t::discarded:
default:
JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
}
@ -4179,6 +4194,12 @@ void from_json(const BasicJsonType& j, ArithmeticType& val)
break;
}
case value_t::null:
case value_t::object:
case value_t::array:
case value_t::string:
case value_t::binary:
case value_t::discarded:
default:
JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
}
@ -4402,6 +4423,14 @@ template<typename IteratorType> class iteration_proxy_value
return anchor.key();
// use an empty key for all primitive types
case value_t::null:
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
return empty_str;
}
@ -8360,6 +8389,7 @@ class binary_reader
result = parse_ubjson_internal();
break;
case input_format_t::json: // LCOV_EXCL_LINE
default: // LCOV_EXCL_LINE
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
}
@ -10519,6 +10549,20 @@ class binary_reader
return sax->number_unsigned(number_lexer.get_number_unsigned());
case token_type::value_float:
return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
case token_type::uninitialized:
case token_type::literal_true:
case token_type::literal_false:
case token_type::literal_null:
case token_type::value_string:
case token_type::begin_array:
case token_type::begin_object:
case token_type::end_array:
case token_type::end_object:
case token_type::name_separator:
case token_type::value_separator:
case token_type::parse_error:
case token_type::end_of_input:
case token_type::literal_or_value:
default:
return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number"), BasicJsonType()));
}
@ -10721,6 +10765,7 @@ class binary_reader
error_msg += "BSON";
break;
case input_format_t::json: // LCOV_EXCL_LINE
default: // LCOV_EXCL_LINE
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
}
@ -11095,6 +11140,13 @@ class parser
parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), BasicJsonType()));
}
case token_type::uninitialized:
case token_type::end_array:
case token_type::end_object:
case token_type::name_separator:
case token_type::value_separator:
case token_type::end_of_input:
case token_type::literal_or_value:
default: // the last token was unexpected
{
return sax->parse_error(m_lexer.get_position(),
@ -11518,6 +11570,14 @@ class iter_impl
break;
}
case value_t::null:
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
{
m_it.primitive_iterator = primitive_iterator_t();
@ -11614,6 +11674,13 @@ class iter_impl
break;
}
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
{
m_it.primitive_iterator.set_begin();
@ -11644,6 +11711,14 @@ class iter_impl
break;
}
case value_t::null:
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
{
m_it.primitive_iterator.set_end();
@ -11678,6 +11753,13 @@ class iter_impl
case value_t::null:
JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
{
if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
@ -11712,6 +11794,14 @@ class iter_impl
return &*m_it.array_iterator;
}
case value_t::null:
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
{
if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
@ -11757,6 +11847,14 @@ class iter_impl
break;
}
case value_t::null:
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
{
++m_it.primitive_iterator;
@ -11800,6 +11898,14 @@ class iter_impl
break;
}
case value_t::null:
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
{
--m_it.primitive_iterator;
@ -11833,6 +11939,14 @@ class iter_impl
case value_t::array:
return (m_it.array_iterator == other.m_it.array_iterator);
case value_t::null:
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
return (m_it.primitive_iterator == other.m_it.primitive_iterator);
}
@ -11870,6 +11984,14 @@ class iter_impl
case value_t::array:
return (m_it.array_iterator < other.m_it.array_iterator);
case value_t::null:
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
return (m_it.primitive_iterator < other.m_it.primitive_iterator);
}
@ -11921,6 +12043,14 @@ class iter_impl
break;
}
case value_t::null:
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
{
m_it.primitive_iterator += i;
@ -11989,6 +12119,14 @@ class iter_impl
case value_t::array:
return m_it.array_iterator - other.m_it.array_iterator;
case value_t::null:
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
return m_it.primitive_iterator - other.m_it.primitive_iterator;
}
@ -12013,6 +12151,13 @@ class iter_impl
case value_t::null:
JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
{
if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))
@ -12632,6 +12777,13 @@ class json_pointer
an error situation, because primitive values may only occur as
single value; that is, with an empty list of reference tokens.
*/
case detail::value_t::string:
case detail::value_t::boolean:
case detail::value_t::number_integer:
case detail::value_t::number_unsigned:
case detail::value_t::number_float:
case detail::value_t::binary:
case detail::value_t::discarded:
default:
JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", j));
}
@ -12704,6 +12856,14 @@ class json_pointer
break;
}
case detail::value_t::null:
case detail::value_t::string:
case detail::value_t::boolean:
case detail::value_t::number_integer:
case detail::value_t::number_unsigned:
case detail::value_t::number_float:
case detail::value_t::binary:
case detail::value_t::discarded:
default:
JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
}
@ -12746,6 +12906,14 @@ class json_pointer
break;
}
case detail::value_t::null:
case detail::value_t::string:
case detail::value_t::boolean:
case detail::value_t::number_integer:
case detail::value_t::number_unsigned:
case detail::value_t::number_float:
case detail::value_t::binary:
case detail::value_t::discarded:
default:
JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
}
@ -12793,6 +12961,14 @@ class json_pointer
break;
}
case detail::value_t::null:
case detail::value_t::string:
case detail::value_t::boolean:
case detail::value_t::number_integer:
case detail::value_t::number_unsigned:
case detail::value_t::number_float:
case detail::value_t::binary:
case detail::value_t::discarded:
default:
JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
}
@ -12835,6 +13011,14 @@ class json_pointer
break;
}
case detail::value_t::null:
case detail::value_t::string:
case detail::value_t::boolean:
case detail::value_t::number_integer:
case detail::value_t::number_unsigned:
case detail::value_t::number_float:
case detail::value_t::binary:
case detail::value_t::discarded:
default:
JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
}
@ -12905,6 +13089,14 @@ class json_pointer
break;
}
case detail::value_t::null:
case detail::value_t::string:
case detail::value_t::boolean:
case detail::value_t::number_integer:
case detail::value_t::number_unsigned:
case detail::value_t::number_float:
case detail::value_t::binary:
case detail::value_t::discarded:
default:
{
// we do not expect primitive values if there is still a
@ -13038,6 +13230,14 @@ class json_pointer
break;
}
case detail::value_t::null:
case detail::value_t::string:
case detail::value_t::boolean:
case detail::value_t::number_integer:
case detail::value_t::number_unsigned:
case detail::value_t::number_float:
case detail::value_t::binary:
case detail::value_t::discarded:
default:
{
// add primitive value with its reference string
@ -13403,6 +13603,15 @@ class binary_writer
break;
}
case value_t::null:
case value_t::array:
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
{
JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name()), j));;
@ -13728,6 +13937,7 @@ class binary_writer
break;
}
case value_t::discarded:
default:
break;
}
@ -14049,6 +14259,7 @@ class binary_writer
break;
}
case value_t::discarded:
default:
break;
}
@ -14253,6 +14464,7 @@ class binary_writer
break;
}
case value_t::discarded:
default:
break;
}
@ -14273,6 +14485,7 @@ class binary_writer
if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
{
JSON_THROW(out_of_range::create(409, "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")", j));
static_cast<void>(j);
}
return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
@ -14504,6 +14717,7 @@ class binary_writer
return header_size + 0ul;
// LCOV_EXCL_START
case value_t::discarded:
default:
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
return 0ul;
@ -14550,6 +14764,7 @@ class binary_writer
return write_bson_null(name);
// LCOV_EXCL_START
case value_t::discarded:
default:
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
return;
@ -14840,6 +15055,7 @@ class binary_writer
case value_t::object:
return '{';
case value_t::discarded:
default: // discarded values
return 'N';
}
@ -14889,8 +15105,10 @@ class binary_writer
void write_compact_float(const number_float_t n, detail::input_format_t format)
{
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
@ -14907,7 +15125,9 @@ class binary_writer
: get_msgpack_float_prefix(n));
write_number(n);
}
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
}
public:
@ -16048,8 +16268,10 @@ char* to_chars(char* first, const char* last, FloatType value)
*first++ = '-';
}
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
if (value == 0) // +-0
{
*first++ = '0';
@ -16058,7 +16280,9 @@ char* to_chars(char* first, const char* last, FloatType value)
*first++ = '0';
return first;
}
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
@ -18215,6 +18439,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
break;
}
case value_t::discarded:
default:
{
object = nullptr; // silence warning, see #821
@ -18372,6 +18597,12 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
break;
}
case value_t::null:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::discarded:
default:
{
break;
@ -18443,6 +18674,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
break;
}
case value_t::null:
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
break;
}
@ -19207,6 +19446,11 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
break;
}
case value_t::null:
case value_t::object:
case value_t::array:
case value_t::binary:
case value_t::discarded:
default:
break;
}
@ -19263,6 +19507,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
break;
}
case value_t::null:
case value_t::discarded:
default:
JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " + std::string(first.m_object->type_name()), *first.m_object));
}
@ -19362,6 +19608,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
break;
}
case value_t::null:
case value_t::discarded:
default:
break;
}
@ -21386,6 +21634,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
break;
}
case value_t::null:
case value_t::discarded:
default:
JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
}
@ -21502,6 +21752,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
break;
}
case value_t::null:
case value_t::discarded:
default:
JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
}
@ -22257,6 +22509,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
return m_value.object->empty();
}
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
{
// all other types are nonempty
@ -22330,6 +22589,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
return m_value.object->size();
}
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
{
// all other types have size 1
@ -22395,6 +22661,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
return m_value.object->max_size();
}
case value_t::null:
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
{
// all other types have max_size() == size()
@ -22502,6 +22776,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
break;
}
case value_t::null:
case value_t::discarded:
default:
break;
}
@ -23434,8 +23710,10 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
*/
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
{
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
const auto lhs_type = lhs.type();
const auto rhs_type = rhs.type();
@ -23470,6 +23748,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
case value_t::binary:
return *lhs.m_value.binary == *rhs.m_value.binary;
case value_t::discarded:
default:
return false;
}
@ -23500,7 +23779,9 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
}
return false;
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
}
/*!
@ -23634,6 +23915,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
case value_t::binary:
return (*lhs.m_value.binary) < (*rhs.m_value.binary);
case value_t::discarded:
default:
return false;
}
@ -24258,6 +24540,9 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
return "binary";
case value_t::discarded:
return "discarded";
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
default:
return "number";
}
@ -25595,6 +25880,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
}
// if there exists a parent it cannot be primitive
case value_t::string: // LCOV_EXCL_LINE
case value_t::boolean: // LCOV_EXCL_LINE
case value_t::number_integer: // LCOV_EXCL_LINE
case value_t::number_unsigned: // LCOV_EXCL_LINE
case value_t::number_float: // LCOV_EXCL_LINE
case value_t::binary: // LCOV_EXCL_LINE
case value_t::discarded: // LCOV_EXCL_LINE
default: // LCOV_EXCL_LINE
JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
}
@ -25754,6 +26046,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
break;
}
case patch_operations::invalid:
default:
{
// op must be "add", "remove", "replace", "move", "copy", or
@ -25910,6 +26203,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
break;
}
case value_t::null:
case value_t::string:
case value_t::boolean:
case value_t::number_integer:
case value_t::number_unsigned:
case value_t::number_float:
case value_t::binary:
case value_t::discarded:
default:
{
// both primitive type: replace value

View File

@ -90,6 +90,16 @@ foreach(file ${files})
endif()
endforeach()
# disable exceptions for test-disabled_exceptions
target_compile_definitions(test-disabled_exceptions PUBLIC JSON_NOEXCEPTION)
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
target_compile_options(test-disabled_exceptions PUBLIC -fno-exceptions)
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
# disabled due to https://github.com/nlohmann/json/discussions/2824
#target_compile_options(test-disabled_exceptions PUBLIC /EH)
#target_compile_definitions(test-disabled_exceptions PUBLIC _HAS_EXCEPTIONS=0)
endif()
add_executable(json_unit EXCLUDE_FROM_ALL $<TARGET_OBJECTS:doctest_main> ${files})
target_compile_definitions(json_unit PRIVATE DOCTEST_CONFIG_SUPER_FAST_ASSERTS)
target_compile_options(json_unit PRIVATE

View File

@ -108,6 +108,7 @@ struct my_allocator : std::allocator<T>
throw std::bad_alloc();
}
static_cast<void>(p); // fix MSVC's C4100 warning
p->~T();
}

View File

@ -1089,7 +1089,7 @@ TEST_CASE_TEMPLATE("deserialization of different character types (UTF-8)", T,
char, unsigned char, std::uint8_t)
{
// a star emoji
std::vector<T> v = {'"', static_cast<T>(0xe2), static_cast<T>(0xad), static_cast<T>(0x90), static_cast<T>(0xef), static_cast<T>(0xb8), static_cast<T>(0x8f), '"'};
std::vector<T> v = {'"', static_cast<T>(0xe2u), static_cast<T>(0xadu), static_cast<T>(0x90u), static_cast<T>(0xefu), static_cast<T>(0xb8u), static_cast<T>(0x8fu), '"'};
CHECK(json::parse(v).dump(-1, ' ', true) == "\"\\u2b50\\ufe0f\"");
CHECK(json::accept(v));

View File

@ -0,0 +1,66 @@
/*
__ _____ _____ _____
__| | __| | | | JSON for Modern C++ (test suite)
| | |__ | | | | | | version 3.9.1
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
SPDX-License-Identifier: MIT
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "doctest_compatibility.h"
#include <nlohmann/json.hpp>
using json = nlohmann::json;
/////////////////////////////////////////////////////////////////////
// for #2824
/////////////////////////////////////////////////////////////////////
class sax_no_exception : public nlohmann::detail::json_sax_dom_parser<json>
{
public:
explicit sax_no_exception(json& j) : nlohmann::detail::json_sax_dom_parser<json>(j, false) {}
static bool parse_error(std::size_t /*position*/, const std::string& /*last_token*/, const json::exception& ex)
{
error_string = new std::string(ex.what()); // NOLINT(cppcoreguidelines-owning-memory)
return false;
}
static std::string* error_string;
};
std::string* sax_no_exception::error_string = nullptr;
TEST_CASE("Tests with disabled exceptions")
{
SECTION("issue #2824 - encoding of json::exception::what()")
{
json j;
sax_no_exception sax(j);
CHECK (!json::sax_parse("xyz", &sax));
CHECK(*sax_no_exception::error_string == "[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - invalid literal; last read: 'x'");
delete sax_no_exception::error_string; // NOLINT(cppcoreguidelines-owning-memory)
}
}

View File

@ -156,6 +156,26 @@ struct adl_serializer<NonDefaultConstructible>
};
} // namespace nlohmann
/////////////////////////////////////////////////////////////////////
// for #2824
/////////////////////////////////////////////////////////////////////
class sax_no_exception : public nlohmann::detail::json_sax_dom_parser<json>
{
public:
explicit sax_no_exception(json& j) : nlohmann::detail::json_sax_dom_parser<json>(j, false) {}
static bool parse_error(std::size_t /*position*/, const std::string& /*last_token*/, const json::exception& ex)
{
error_string = new std::string(ex.what()); // NOLINT(cppcoreguidelines-owning-memory)
return false;
}
static std::string* error_string;
};
std::string* sax_no_exception::error_string = nullptr;
TEST_CASE("regression tests 2")
{
@ -621,6 +641,16 @@ TEST_CASE("regression tests 2")
}
}
SECTION("issue #2824 - encoding of json::exception::what()")
{
json j;
sax_no_exception sax(j);
CHECK (!json::sax_parse("xyz", &sax));
CHECK(*sax_no_exception::error_string == "[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - invalid literal; last read: 'x'");
delete sax_no_exception::error_string; // NOLINT(cppcoreguidelines-owning-memory)
}
SECTION("issue #2825 - Properly constrain the basic_json conversion operator")
{
static_assert(std::is_copy_assignable<nlohmann::ordered_json>::value, "");

View File

@ -816,7 +816,10 @@ class Evil
public:
Evil() = default;
template <typename T>
Evil(T t) : m_i(sizeof(t)) {}
Evil(T t) : m_i(sizeof(t))
{
static_cast<void>(t); // fix MSVC's C4100 warning
}
int m_i = 0;
};