mirror of
https://github.com/nlohmann/json.git
synced 2026-10-11 08:57:15 +00:00
Make view lookups last-wins and chained access safe
* Lookups (operator[], at, find, contains, count, value, JSON pointers) return the last member of a duplicate key, as materialize() and parse() keep it. * operator[] on a discarded view returns a discarded view instead of throwing, so v["a"]["b"] is safe for a missing "a". * operator[] and at() take any integer type (not only int and size_t), fixing ambiguous calls with unsigned, long, std::int64_t, ... * Fix the operator[] documentation, which claimed a discarded view for a type mismatch where type_error.305 is thrown. Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
16 files changed
+306
-84
No files matched your search
@@ -240,13 +240,18 @@ class basic_json_view
|
||||
// element access //
|
||||
////////////////////
|
||||
|
||||
/// the value of the member with this key (the first one, should the key
|
||||
/// occur more than once); a discarded view if there is none. Throws
|
||||
/// type_error.305 if this is not an object.
|
||||
/// the value of the member with this key (the last one, should the key
|
||||
/// occur more than once); a discarded view if there is none, or if this
|
||||
/// is a discarded view (so that v["a"]["b"] is safe). Throws type_error.305
|
||||
/// if this is any other value but an object.
|
||||
NLOHMANN_VIEW_ALWAYS_INLINE basic_json_view operator[](string_view_t key) const
|
||||
{
|
||||
if (NLOHMANN_VIEW_UNLIKELY(!is_object()))
|
||||
{
|
||||
if (is_discarded())
|
||||
{
|
||||
return basic_json_view();
|
||||
}
|
||||
detail::view::throw_type_error(305, "cannot use operator[] with a string argument with ", type_name());
|
||||
}
|
||||
return lookup(key);
|
||||
@@ -263,31 +268,43 @@ class basic_json_view
|
||||
}
|
||||
|
||||
/// the element at this index; a discarded view if the index is out of
|
||||
/// range. Throws type_error.305 if this is not an array.
|
||||
/// range, or if this is a discarded view. Throws type_error.305 if this is
|
||||
/// any other value but an array.
|
||||
basic_json_view operator[](size_type idx) const
|
||||
{
|
||||
if (NLOHMANN_VIEW_UNLIKELY(!is_array()))
|
||||
{
|
||||
if (is_discarded())
|
||||
{
|
||||
return basic_json_view();
|
||||
}
|
||||
detail::view::throw_type_error(305, "cannot use operator[] with a numeric argument with ", type_name());
|
||||
}
|
||||
return idx < m_node->len ? basic_json_view(m_doc, detail::view::element_at(m_node, idx)) : basic_json_view();
|
||||
}
|
||||
|
||||
/// (an int argument would be ambiguous between size_type and const char*)
|
||||
basic_json_view operator[](int idx) const
|
||||
/// any other integer type (int, unsigned, long, std::int64_t, ...; a
|
||||
/// single overload for size_type alone would be ambiguous for all of them
|
||||
/// and for const char*); negative values are out of range
|
||||
template < typename IntegerType, typename std::enable_if < detail::view::is_index_type<IntegerType>::value, int >::type = 0 >
|
||||
basic_json_view operator[](IntegerType idx) const
|
||||
{
|
||||
return operator[](static_cast<size_type>(idx));
|
||||
return operator[](detail::view::to_index<size_type>(idx));
|
||||
}
|
||||
|
||||
/// the value a JSON pointer refers to; a discarded view if a key is
|
||||
/// missing or an index is out of range. Other errors throw what const
|
||||
/// basic_json::operator[] throws.
|
||||
/// missing or an index is out of range, or if this is a discarded view.
|
||||
/// Other errors throw what const basic_json::operator[] throws.
|
||||
basic_json_view operator[](const json_pointer& ptr) const
|
||||
{
|
||||
if (NLOHMANN_VIEW_UNLIKELY(is_discarded()))
|
||||
{
|
||||
return basic_json_view();
|
||||
}
|
||||
return detail::view::resolve_pointer(*this, detail::json_pointer_access::reference_tokens(ptr), detail::view::pointer_mode::unchecked);
|
||||
}
|
||||
|
||||
/// the value of the member with this key (the first one, should the key
|
||||
/// the value of the member with this key (the last one, should the key
|
||||
/// occur more than once). Throws type_error.304 if this is not an object,
|
||||
/// and out_of_range.403 if there is no such member.
|
||||
basic_json_view at(string_view_t key) const
|
||||
@@ -329,9 +346,12 @@ class basic_json_view
|
||||
return basic_json_view(m_doc, detail::view::element_at(m_node, idx));
|
||||
}
|
||||
|
||||
basic_json_view at(int idx) const
|
||||
/// any other integer type, see operator[]; negative values are out of
|
||||
/// range
|
||||
template < typename IntegerType, typename std::enable_if < detail::view::is_index_type<IntegerType>::value, int >::type = 0 >
|
||||
basic_json_view at(IntegerType idx) const
|
||||
{
|
||||
return at(static_cast<size_type>(idx));
|
||||
return at(detail::view::to_index<size_type>(idx));
|
||||
}
|
||||
|
||||
/// the value a JSON pointer refers to; throws what basic_json::at()
|
||||
@@ -342,7 +362,7 @@ class basic_json_view
|
||||
}
|
||||
|
||||
/// the member with this key converted to T, or the default value if there
|
||||
/// is no such member (the first one, should the key occur more than
|
||||
/// is no such member (the last one, should the key occur more than
|
||||
/// once). Throws type_error.306 if this is not an object.
|
||||
template < typename T, typename std::enable_if < !std::is_same<typename std::decay<T>::type, const char*>::value, int >::type = 0 >
|
||||
T value(string_view_t key, const T& default_value) const
|
||||
@@ -407,7 +427,7 @@ class basic_json_view
|
||||
// lookup //
|
||||
////////////
|
||||
|
||||
/// an iterator to the member with this key (the first one, should the
|
||||
/// an iterator to the member with this key (the last one, should the
|
||||
/// key occur more than once), or end(); end() also for non-objects
|
||||
iterator find(string_view_t key) const
|
||||
{
|
||||
@@ -585,7 +605,7 @@ class basic_json_view
|
||||
: m_doc(d), m_node(n)
|
||||
{}
|
||||
|
||||
/// the value of the first member with this key, or a discarded view
|
||||
/// the value of the last member with this key, or a discarded view
|
||||
/// (object required)
|
||||
NLOHMANN_VIEW_ALWAYS_INLINE basic_json_view lookup(string_view_t key) const noexcept
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user