mirror of
https://github.com/nlohmann/json.git
synced 2026-10-11 08:57:15 +00:00
Remove the conversion to bool from json_view
explicit operator bool meant "refers to a value", which silently differs from what a basic_json converts to. Use !v.is_discarded() instead. Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
11 files changed
+19
-70
No files matched your search
@@ -4,8 +4,8 @@
|
|||||||
basic_json_view() noexcept = default;
|
basic_json_view() noexcept = default;
|
||||||
```
|
```
|
||||||
|
|
||||||
Creates an invalid (discarded) view: [`type()`](type.md) is `#!cpp value_t::discarded`,
|
Creates an invalid (discarded) view: [`type()`](type.md) is `#!cpp value_t::discarded` and
|
||||||
[`is_discarded()`](is_discarded.md) is `#!cpp true`, and `#!cpp explicit operator bool()` is `#!cpp false`.
|
[`is_discarded()`](is_discarded.md) is `#!cpp true`.
|
||||||
|
|
||||||
This is the only constructor a caller can use directly. Every other view is obtained from a
|
This is the only constructor a caller can use directly. Every other view is obtained from a
|
||||||
[`basic_json_document`](../basic_json_document/index.md), via [`root()`](../basic_json_document/root.md) or (once
|
[`basic_json_document`](../basic_json_document/index.md), via [`root()`](../basic_json_document/root.md) or (once
|
||||||
@@ -43,7 +43,6 @@ placeholder for "no value yet" and later be assigned a real view.
|
|||||||
## See also
|
## See also
|
||||||
|
|
||||||
- [is_discarded](is_discarded.md) - return whether the view is invalid
|
- [is_discarded](is_discarded.md) - return whether the view is invalid
|
||||||
- [operator bool](operator_bool.md) - return whether the view refers to a value
|
|
||||||
- [root](../basic_json_document/root.md) - the view of a document's root value
|
- [root](../basic_json_document/root.md) - the view of a document's root value
|
||||||
|
|
||||||
## Version history
|
## Version history
|
||||||
|
|||||||
@@ -62,7 +62,6 @@ element access, iteration, `get<T>()`, JSON Pointer support, `dump()`, or compar
|
|||||||
- [**is_primitive**](is_primitive.md) - return whether the type is primitive
|
- [**is_primitive**](is_primitive.md) - return whether the type is primitive
|
||||||
- [**is_structured**](is_structured.md) - return whether the type is structured
|
- [**is_structured**](is_structured.md) - return whether the type is structured
|
||||||
- [**is_discarded**](is_discarded.md) - return whether the view is invalid
|
- [**is_discarded**](is_discarded.md) - return whether the view is invalid
|
||||||
- [**operator bool**](operator_bool.md) - return whether the view refers to a value
|
|
||||||
|
|
||||||
### Capacity
|
### Capacity
|
||||||
|
|
||||||
|
|||||||
@@ -23,8 +23,9 @@ Constant.
|
|||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
`#!cpp v.is_discarded()` and `#!cpp !static_cast<bool>(v)` are equivalent; use whichever reads better at the call
|
A `basic_json_view` is not convertible to `#!cpp bool`: such a conversion would mean "refers to a value", whereas
|
||||||
site.
|
`basic_json` converts to the `#!cpp bool` it holds, so the same code would silently behave differently. Test
|
||||||
|
`#!cpp !v.is_discarded()` explicitly.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
@@ -45,7 +46,6 @@ site.
|
|||||||
|
|
||||||
## See also
|
## See also
|
||||||
|
|
||||||
- [operator bool](operator_bool.md) - return whether the view refers to a value
|
|
||||||
- [(constructor)](basic_json_view.md) - the default constructor creates a discarded view
|
- [(constructor)](basic_json_view.md) - the default constructor creates a discarded view
|
||||||
- [is_discarded (basic_json_document)](../basic_json_document/is_discarded.md) - return whether the last parse failed
|
- [is_discarded (basic_json_document)](../basic_json_document/is_discarded.md) - return whether the last parse failed
|
||||||
- [`BasicJsonType::is_discarded`](../basic_json/is_discarded.md) - the corresponding function of `basic_json`
|
- [`BasicJsonType::is_discarded`](../basic_json/is_discarded.md) - the corresponding function of `basic_json`
|
||||||
|
|||||||
@@ -1,46 +0,0 @@
|
|||||||
# <small>nlohmann::basic_json_view::</small>operator bool
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
explicit operator bool() const noexcept;
|
|
||||||
```
|
|
||||||
|
|
||||||
Returns whether this view refers to a value, i.e. the negation of [`is_discarded()`](is_discarded.md). Being
|
|
||||||
`#!cpp explicit`, this conversion is only considered in a boolean context (`#!cpp if (v)`, `#!cpp !v`, `#!cpp v &&
|
|
||||||
...`), not for implicit conversions to other types.
|
|
||||||
|
|
||||||
## Return value
|
|
||||||
|
|
||||||
`#!cpp true` if the view refers to a value, `#!cpp false` if it is [discarded](is_discarded.md).
|
|
||||||
|
|
||||||
## Exception safety
|
|
||||||
|
|
||||||
No-throw guarantee: this function never throws exceptions.
|
|
||||||
|
|
||||||
## Complexity
|
|
||||||
|
|
||||||
Constant.
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
??? example
|
|
||||||
|
|
||||||
The example below classifies several parsed documents by the type of their root value, without materializing any
|
|
||||||
of them into a `BasicJsonType` value.
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
--8<-- "examples/basic_json_view__type_predicates.cpp"
|
|
||||||
```
|
|
||||||
|
|
||||||
Output:
|
|
||||||
|
|
||||||
```json
|
|
||||||
--8<-- "examples/basic_json_view__type_predicates.output"
|
|
||||||
```
|
|
||||||
|
|
||||||
## See also
|
|
||||||
|
|
||||||
- [is_discarded](is_discarded.md) - return whether the view is invalid
|
|
||||||
|
|
||||||
## Version history
|
|
||||||
|
|
||||||
- Added in version 3.13.0.
|
|
||||||
@@ -8,10 +8,10 @@ int main()
|
|||||||
// the default constructor is the only public one: it creates an invalid
|
// the default constructor is the only public one: it creates an invalid
|
||||||
// (discarded) view, useful as a "no value yet" placeholder
|
// (discarded) view, useful as a "no value yet" placeholder
|
||||||
nlohmann::json_view v;
|
nlohmann::json_view v;
|
||||||
std::cout << static_cast<bool>(v) << ' ' << v.is_discarded() << '\n';
|
std::cout << v.is_discarded() << '\n';
|
||||||
|
|
||||||
// views are trivially copyable handles (two pointers); the document owns
|
// views are trivially copyable handles (two pointers); the document owns
|
||||||
// the actual data
|
// the actual data
|
||||||
nlohmann::json_view copy = v;
|
nlohmann::json_view copy = v;
|
||||||
std::cout << static_cast<bool>(copy) << '\n';
|
std::cout << copy.is_discarded() << '\n';
|
||||||
}
|
}
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
false true
|
true
|
||||||
false
|
true
|
||||||
@@ -35,8 +35,8 @@ int main()
|
|||||||
// parse without exceptions, are both discarded
|
// parse without exceptions, are both discarded
|
||||||
nlohmann::json_view invalid;
|
nlohmann::json_view invalid;
|
||||||
json_document failed = json_document::parse("not json", /* allow_exceptions */ false);
|
json_document failed = json_document::parse("not json", /* allow_exceptions */ false);
|
||||||
std::cout << static_cast<bool>(invalid) << ' ' << invalid.is_discarded() << '\n';
|
std::cout << invalid.is_discarded() << '\n';
|
||||||
std::cout << static_cast<bool>(failed.root()) << ' ' << failed.root().is_discarded() << '\n';
|
std::cout << failed.root().is_discarded() << '\n';
|
||||||
|
|
||||||
// type() returns the same value_t enumeration as basic_json::type()
|
// type() returns the same value_t enumeration as basic_json::type()
|
||||||
std::cout << (d_object.root().type() == nlohmann::json::value_t::object) << '\n';
|
std::cout << (d_object.root().type() == nlohmann::json::value_t::object) << '\n';
|
||||||
|
|||||||
@@ -7,6 +7,6 @@ true
|
|||||||
true true
|
true true
|
||||||
true false
|
true false
|
||||||
false
|
false
|
||||||
false true
|
true
|
||||||
false true
|
true
|
||||||
true
|
true
|
||||||
@@ -266,7 +266,6 @@ nav:
|
|||||||
- 'is_string': api/basic_json_view/is_string.md
|
- 'is_string': api/basic_json_view/is_string.md
|
||||||
- 'is_structured': api/basic_json_view/is_structured.md
|
- 'is_structured': api/basic_json_view/is_structured.md
|
||||||
- 'materialize': api/basic_json_view/materialize.md
|
- 'materialize': api/basic_json_view/materialize.md
|
||||||
- 'operator bool': api/basic_json_view/operator_bool.md
|
|
||||||
- 'size': api/basic_json_view/size.md
|
- 'size': api/basic_json_view/size.md
|
||||||
- 'source_offset': api/basic_json_view/source_offset.md
|
- 'source_offset': api/basic_json_view/source_offset.md
|
||||||
- 'type': api/basic_json_view/type.md
|
- 'type': api/basic_json_view/type.md
|
||||||
|
|||||||
@@ -156,12 +156,6 @@ class basic_json_view
|
|||||||
return type() == value_t::discarded;
|
return type() == value_t::discarded;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// false for discarded views
|
|
||||||
explicit operator bool() const noexcept
|
|
||||||
{
|
|
||||||
return m_node != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////
|
//////////////
|
||||||
// capacity //
|
// capacity //
|
||||||
//////////////
|
//////////////
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ template<typename... Args>
|
|||||||
using accept_call_t = decltype(json_document::accept(std::declval<Args>()...));
|
using accept_call_t = decltype(json_document::accept(std::declval<Args>()...));
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
using read_call_t = decltype(std::declval<json_document&>().read(std::declval<Args>()...));
|
using read_call_t = decltype(std::declval<json_document&>().read(std::declval<Args>()...));
|
||||||
|
template<typename View>
|
||||||
|
using bool_conversion_t = decltype(static_cast<bool>(std::declval<View>()));
|
||||||
|
|
||||||
#if !defined(JSON_NOEXCEPTION)
|
#if !defined(JSON_NOEXCEPTION)
|
||||||
// the exception parse() throws for a text, or "" if it accepts it
|
// the exception parse() throws for a text, or "" if it accepts it
|
||||||
@@ -155,7 +157,6 @@ TEST_CASE("json_view")
|
|||||||
CHECK(v.is_primitive() == j.is_primitive());
|
CHECK(v.is_primitive() == j.is_primitive());
|
||||||
CHECK(v.is_structured() == j.is_structured());
|
CHECK(v.is_structured() == j.is_structured());
|
||||||
CHECK(!v.is_discarded());
|
CHECK(!v.is_discarded());
|
||||||
CHECK(static_cast<bool>(v));
|
|
||||||
CHECK(v.size() == j.size());
|
CHECK(v.size() == j.size());
|
||||||
CHECK(v.empty() == j.empty());
|
CHECK(v.empty() == j.empty());
|
||||||
CHECK(v.materialize() == j);
|
CHECK(v.materialize() == j);
|
||||||
@@ -163,7 +164,6 @@ TEST_CASE("json_view")
|
|||||||
|
|
||||||
const json_view invalid{};
|
const json_view invalid{};
|
||||||
CHECK(invalid.is_discarded());
|
CHECK(invalid.is_discarded());
|
||||||
CHECK(!static_cast<bool>(invalid));
|
|
||||||
CHECK(invalid.type() == json::value_t::discarded);
|
CHECK(invalid.type() == json::value_t::discarded);
|
||||||
CHECK(invalid.size() == 0);
|
CHECK(invalid.size() == 0);
|
||||||
CHECK(invalid.empty());
|
CHECK(invalid.empty());
|
||||||
@@ -380,6 +380,10 @@ TEST_CASE("json_view")
|
|||||||
static_assert(is_detected<read_call_t, const char*, bool>::value, "read(ptr, bool) is valid");
|
static_assert(is_detected<read_call_t, const char*, bool>::value, "read(ptr, bool) is valid");
|
||||||
static_assert(!is_detected<read_call_t, const char*, std::size_t>::value, "read(ptr, len) must not compile");
|
static_assert(!is_detected<read_call_t, const char*, std::size_t>::value, "read(ptr, len) must not compile");
|
||||||
|
|
||||||
|
// json_view has no conversion to bool: unlike basic_json's, it would
|
||||||
|
// mean "exists", not "is not null"; use is_discarded()
|
||||||
|
static_assert(!is_detected<bool_conversion_t, json_view>::value, "json_view must not convert to bool");
|
||||||
|
|
||||||
// the valid calls still work
|
// the valid calls still work
|
||||||
const char* const text = "[1]";
|
const char* const text = "[1]";
|
||||||
CHECK(json_document::parse(text, true).root().is_array());
|
CHECK(json_document::parse(text, true).root().is_array());
|
||||||
|
|||||||
Reference in new issue
Block a user