JsonBuilder - Fix parameter ambiguity for push_back and AddValue (#28)
All of the AddValue methods (AddValue, push_front, push_back) have two overloads: - `(..., T const& data)` - `(..., JsonType type, unsigned cbData = 0, void const* pbData = NULL)` For the second overload, the default values are convenient. They provide a convenient syntax for adding the no-data values like null, array, and object, e.g. `builder.push_back(parent, name, JsonNull)`. However, these defaults are ambiguous and a bit dangerous: - `builder.push_back(parent, name, something)` could be a call to the first overload or it could be a call to the second overload with defaulted `0, NULL` parameters. - `builder.push_back(parent, name, type, 43)` compiles without warning and silently leaves the value uninitialized. The uninitialized case is useful but rare and should only happen with explicit NULL, not by default. Fix is to remove the defaults: - `(..., T const& data)` - `(..., JsonType type, unsigned cbData, void const* pbData)` However, this breaks the `builder.push_back(parent, name, JsonNull)` syntax. Restore that syntax by adding `JsonType` to the list of valid types accepted by the first overload. Now there is no ambiguity between the two overloads, and you can't call the cbData + pbData overload without both size and pointer. This intentionally breaks `builder.push_back(parent, name, type, size)`, which must be fixed by `builder.push_back(parent, name, type, size, NULL)` (assuming it wasn't a bug).
This commit is contained in:
Родитель
450a68f1bb
Коммит
4f5fa7bfbf
|
@ -1283,8 +1283,8 @@ class JsonBuilder
|
|||
const_iterator const& itParent,
|
||||
NameStringView const& name,
|
||||
JsonType type,
|
||||
unsigned cbData = 0,
|
||||
_In_reads_bytes_(cbData) void const* pbData = nullptr)
|
||||
unsigned cbData,
|
||||
_In_reads_bytes_opt_(cbData) void const* pbData)
|
||||
noexcept(false) // may throw bad_alloc, length_error
|
||||
{
|
||||
std::basic_string_view<NameChar> nameView{ name };
|
||||
|
@ -1310,8 +1310,8 @@ class JsonBuilder
|
|||
const_iterator const& itParent,
|
||||
NameStringView const& name,
|
||||
JsonType type,
|
||||
unsigned cbData = 0,
|
||||
_In_reads_bytes_(cbData) void const* pbData = nullptr)
|
||||
unsigned cbData,
|
||||
_In_reads_bytes_opt_(cbData) void const* pbData)
|
||||
noexcept(false) // may throw bad_alloc, length_error
|
||||
{
|
||||
std::basic_string_view<NameChar> nameView{ name };
|
||||
|
@ -1337,8 +1337,8 @@ class JsonBuilder
|
|||
const_iterator const& itParent,
|
||||
NameStringView const& name,
|
||||
JsonType type,
|
||||
unsigned cbData = 0,
|
||||
_In_reads_bytes_(cbData) void const* pbData = nullptr)
|
||||
unsigned cbData,
|
||||
_In_reads_bytes_opt_(cbData) void const* pbData)
|
||||
noexcept(false) // may throw bad_alloc, length_error
|
||||
{
|
||||
std::basic_string_view<NameChar> nameView{ name };
|
||||
|
@ -1357,6 +1357,7 @@ class JsonBuilder
|
|||
|
||||
Data must be a supported type. Supported types include:
|
||||
|
||||
- For null, array, object: JsonType (JsonNull, JsonArray, JsonObject).
|
||||
- For boolean data: bool.
|
||||
- For UTF-8 string data: std::string_view, char*.
|
||||
- For integer data: signed and unsigned char, short, int, long, long long.
|
||||
|
@ -1401,6 +1402,7 @@ class JsonBuilder
|
|||
|
||||
Data must be a supported type. Supported types include:
|
||||
|
||||
- For null, array, object: JsonType (JsonNull, JsonArray, JsonObject).
|
||||
- For boolean data: bool.
|
||||
- For UTF-8 string data: std::string_view, char*.
|
||||
- For integer data: signed and unsigned char, short, int, long, long long.
|
||||
|
@ -1444,6 +1446,7 @@ class JsonBuilder
|
|||
|
||||
Data must be a supported type. Supported types include:
|
||||
|
||||
- For null, array, object: JsonType (JsonNull, JsonArray, JsonObject).
|
||||
- For boolean data: bool.
|
||||
- For UTF-8 string data: std::string_view, char*.
|
||||
- For integer data: signed and unsigned char, short, int, long, long long.
|
||||
|
@ -1602,8 +1605,8 @@ private:
|
|||
const_iterator const& itParent,
|
||||
NameStringView nameView,
|
||||
JsonType type,
|
||||
unsigned cbData = 0,
|
||||
_In_reads_bytes_(cbData) void const* pbData = nullptr)
|
||||
unsigned cbData,
|
||||
_In_reads_bytes_opt_(cbData) void const* pbData)
|
||||
noexcept(false) // may throw bad_alloc, length_error
|
||||
{
|
||||
using char_type = typename JsonInternal::CharTypeOk<typename NameStringView::value_type>::char_type;
|
||||
|
@ -2015,6 +2018,8 @@ JSON_DECLARE_JsonImplementType_AddValueSz(wchar_t);
|
|||
JSON_DECLARE_JsonImplementType_AddValueSz(char16_t);
|
||||
JSON_DECLARE_JsonImplementType_AddValueSz(char32_t);
|
||||
|
||||
JSON_DECLARE_JsonImplementType_AddValue(JsonType, ); // For null, array, object.
|
||||
|
||||
#ifdef __cpp_lib_char8_t // Support u8string_view and char8_t, inline so they work even if lib builds as C++17.
|
||||
|
||||
// JSON_DECLARE_JsonImplementType(std::u8string_view,, ):
|
||||
|
|
|
@ -2026,4 +2026,22 @@ JsonImplementType<UuidStruct>::GetUnchecked(JsonValue const& jsonValue) noexcept
|
|||
emptyUuid;
|
||||
}
|
||||
|
||||
// JsonType
|
||||
|
||||
JsonIterator
|
||||
JsonImplementType<JsonType>::AddValueCommit(
|
||||
JsonBuilder& builder,
|
||||
JsonType type)
|
||||
{
|
||||
// This method is only for 0-size values like null, array, or object.
|
||||
// The following types cannot have 0-size values and should not call this:
|
||||
assert(type != JsonUInt);
|
||||
assert(type != JsonInt);
|
||||
assert(type != JsonFloat);
|
||||
assert(type != JsonBool);
|
||||
assert(type != JsonTime);
|
||||
assert(type != JsonUuid);
|
||||
return builder._newValueCommit(type, 0, nullptr);
|
||||
}
|
||||
|
||||
} // namespace jsonbuilder
|
||||
|
|
Загрузка…
Ссылка в новой задаче