🔀 merge develop branch
This commit is contained in:
parent
61154547d1
commit
72d86154c6
@ -3775,6 +3775,33 @@ struct is_constructible_tuple : std::false_type {};
|
||||
template<typename T1, typename... Args>
|
||||
struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};
|
||||
|
||||
/// type to check if KeyType can be used as object key
|
||||
|
||||
template<typename ComparatorType, typename KeyType, typename ObjectKeyType, typename = void>
|
||||
struct is_key_type_comparable
|
||||
{
|
||||
static constexpr bool value = false;
|
||||
};
|
||||
|
||||
template<typename ComparatorType, typename KeyType, typename ObjectKeyType>
|
||||
struct is_key_type_comparable<ComparatorType, KeyType, ObjectKeyType, void_t<
|
||||
decltype(ComparatorType()(std::declval<KeyType const&>(), std::declval<ObjectKeyType const&>())),
|
||||
decltype(ComparatorType()(std::declval<ObjectKeyType const&>(), std::declval<KeyType const&>()))
|
||||
>>
|
||||
{
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
|
||||
template<typename BasicJsonType, typename KeyType>
|
||||
struct is_usable_as_key_type
|
||||
{
|
||||
static constexpr bool value =
|
||||
is_key_type_comparable<typename BasicJsonType::object_comparator_t, typename BasicJsonType::object_t::key_type, KeyType>::value &&
|
||||
!std::is_same<KeyType, typename BasicJsonType::iterator>::value &&
|
||||
!std::is_same<KeyType, typename BasicJsonType::const_iterator>::value;
|
||||
};
|
||||
|
||||
|
||||
// a naive helper to check if a type is an ordered_map (exploits the fact that
|
||||
// ordered_map inherits capacity() from std::vector)
|
||||
template <typename T>
|
||||
@ -17680,10 +17707,12 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
default:
|
||||
{
|
||||
object = nullptr; // silence warning, see #821
|
||||
// LCOV_EXCL_START
|
||||
if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
|
||||
{
|
||||
JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.10.4", basic_json())); // LCOV_EXCL_LINE
|
||||
JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.10.4", basic_json()));
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -19133,48 +19162,42 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief access specified object element with bounds checking
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/at/
|
||||
reference at(const typename object_t::key_type& key)
|
||||
template < class KeyT, typename detail::enable_if_t <
|
||||
detail::is_usable_as_key_type<basic_json_t, KeyT>::value&& !std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int > = 0 >
|
||||
reference at(const KeyT& key)
|
||||
{
|
||||
// at only works for objects
|
||||
if (JSON_HEDLEY_LIKELY(is_object()))
|
||||
{
|
||||
JSON_TRY
|
||||
{
|
||||
return set_parent(m_value.object->at(key));
|
||||
}
|
||||
JSON_CATCH (std::out_of_range&)
|
||||
{
|
||||
// create better exception explanation
|
||||
JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this));
|
||||
}
|
||||
}
|
||||
else
|
||||
if (JSON_HEDLEY_UNLIKELY(!is_object()))
|
||||
{
|
||||
JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
|
||||
}
|
||||
|
||||
auto it = m_value.object->find(key);
|
||||
if (it == m_value.object->end())
|
||||
{
|
||||
JSON_THROW(out_of_range::create(403, "key '" + std::string(key) + "' not found", *this));
|
||||
}
|
||||
return set_parent(it->second);
|
||||
}
|
||||
|
||||
/// @brief access specified object element with bounds checking
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/at/
|
||||
const_reference at(const typename object_t::key_type& key) const
|
||||
template < class KeyT, typename detail::enable_if_t <
|
||||
detail::is_usable_as_key_type<basic_json_t, KeyT>::value&& !std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int > = 0 >
|
||||
const_reference at(const KeyT& key) const
|
||||
{
|
||||
// at only works for objects
|
||||
if (JSON_HEDLEY_LIKELY(is_object()))
|
||||
{
|
||||
JSON_TRY
|
||||
{
|
||||
return m_value.object->at(key);
|
||||
}
|
||||
JSON_CATCH (std::out_of_range&)
|
||||
{
|
||||
// create better exception explanation
|
||||
JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this));
|
||||
}
|
||||
}
|
||||
else
|
||||
if (JSON_HEDLEY_UNLIKELY(!is_object()))
|
||||
{
|
||||
JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
|
||||
}
|
||||
|
||||
auto it = m_value.object->find(key);
|
||||
if (it == m_value.object->end())
|
||||
{
|
||||
JSON_THROW(out_of_range::create(403, "key '" + std::string(key) + "' not found", *this));
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
/// @brief access specified array element
|
||||
@ -19238,7 +19261,9 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief access specified object element
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
|
||||
reference operator[](const typename object_t::key_type& key)
|
||||
template < class KeyT, typename detail::enable_if_t <
|
||||
detail::is_usable_as_key_type<basic_json_t, KeyT>::value&& !std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int > = 0 >
|
||||
reference operator[](const KeyT& key)
|
||||
{
|
||||
// implicitly convert null value to an empty object
|
||||
if (is_null())
|
||||
@ -19251,7 +19276,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
// operator[] only works for objects
|
||||
if (JSON_HEDLEY_LIKELY(is_object()))
|
||||
{
|
||||
return set_parent(m_value.object->operator[](key));
|
||||
auto result = m_value.object->emplace(key, nullptr);
|
||||
return set_parent(result.first->second);
|
||||
}
|
||||
|
||||
JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
|
||||
@ -19259,13 +19285,16 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief access specified object element
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
|
||||
const_reference operator[](const typename object_t::key_type& key) const
|
||||
template < class KeyT, typename detail::enable_if_t <
|
||||
detail::is_usable_as_key_type<basic_json_t, KeyT>::value&& !std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int > = 0 >
|
||||
const_reference operator[](const KeyT& key) const
|
||||
{
|
||||
// const operator[] only works for objects
|
||||
// operator[] only works for objects
|
||||
if (JSON_HEDLEY_LIKELY(is_object()))
|
||||
{
|
||||
JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
|
||||
return m_value.object->find(key)->second;
|
||||
auto it = m_value.object->find(key);
|
||||
JSON_ASSERT(it != m_value.object->end());
|
||||
return it->second;
|
||||
}
|
||||
|
||||
JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
|
||||
@ -19273,50 +19302,27 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief access specified object element
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
|
||||
template<typename T>
|
||||
JSON_HEDLEY_NON_NULL(2)
|
||||
reference operator[](T* key)
|
||||
template<typename T, std::size_t n>
|
||||
reference operator[](T * (&key)[n])
|
||||
{
|
||||
// implicitly convert null to object
|
||||
if (is_null())
|
||||
{
|
||||
m_type = value_t::object;
|
||||
m_value = value_t::object;
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
// at only works for objects
|
||||
if (JSON_HEDLEY_LIKELY(is_object()))
|
||||
{
|
||||
return set_parent(m_value.object->operator[](key));
|
||||
}
|
||||
|
||||
JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
|
||||
return operator[](static_cast<const T>(key));
|
||||
}
|
||||
|
||||
/// @brief access specified object element
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
|
||||
template<typename T>
|
||||
JSON_HEDLEY_NON_NULL(2)
|
||||
const_reference operator[](T* key) const
|
||||
template<typename T, std::size_t n>
|
||||
const_reference operator[](T * (&key)[n]) const
|
||||
{
|
||||
// at only works for objects
|
||||
if (JSON_HEDLEY_LIKELY(is_object()))
|
||||
{
|
||||
JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
|
||||
return m_value.object->find(key)->second;
|
||||
}
|
||||
|
||||
JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
|
||||
return operator[](static_cast<const T>(key));
|
||||
}
|
||||
|
||||
/// @brief access specified object element with default value
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/value/
|
||||
/// using std::is_convertible in a std::enable_if will fail when using explicit conversions
|
||||
template < class ValueType, typename std::enable_if <
|
||||
template < class KeyType, class ValueType, typename detail::enable_if_t <
|
||||
detail::is_getable<basic_json_t, ValueType>::value
|
||||
&& !std::is_same<value_t, ValueType>::value, int >::type = 0 >
|
||||
ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
|
||||
&& !std::is_same<value_t, ValueType>::value&& detail::is_usable_as_key_type<basic_json_t, KeyType>::value, int > = 0 >
|
||||
typename std::decay<ValueType>::type value(const KeyType& key, ValueType && default_value) const
|
||||
{
|
||||
// at only works for objects
|
||||
if (JSON_HEDLEY_LIKELY(is_object()))
|
||||
@ -19325,10 +19331,10 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
const auto it = find(key);
|
||||
if (it != end())
|
||||
{
|
||||
return it->template get<ValueType>();
|
||||
return it->template get<typename std::decay<ValueType>::type>();
|
||||
}
|
||||
|
||||
return default_value;
|
||||
return std::forward<ValueType>(default_value);
|
||||
}
|
||||
|
||||
JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this));
|
||||
@ -19337,16 +19343,27 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
/// @brief access specified object element with default value
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/value/
|
||||
/// overload for a default value of type const char*
|
||||
string_t value(const typename object_t::key_type& key, const char* default_value) const
|
||||
#if defined(JSON_HAS_CPP_17) // avoid creating a string_t value from default_value
|
||||
template < class KeyType, typename detail::enable_if_t <
|
||||
detail::is_usable_as_key_type<basic_json_t, KeyType>::value, int> = 0>
|
||||
std::string_view value(const KeyType& key, const char* default_value) const
|
||||
{
|
||||
return value(key, std::string_view(default_value));
|
||||
}
|
||||
#else
|
||||
template < class KeyType, typename detail::enable_if_t <
|
||||
detail::is_usable_as_key_type<basic_json_t, KeyType>::value, int> = 0>
|
||||
string_t value(const KeyType& key, const char* default_value) const
|
||||
{
|
||||
return value(key, string_t(default_value));
|
||||
}
|
||||
#endif
|
||||
|
||||
/// @brief access specified object element via JSON Pointer with default value
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/value/
|
||||
template<class ValueType, typename std::enable_if<
|
||||
detail::is_getable<basic_json_t, ValueType>::value, int>::type = 0>
|
||||
ValueType value(const json_pointer& ptr, const ValueType& default_value) const
|
||||
typename std::decay<ValueType>::type value(const json_pointer& ptr, ValueType && default_value) const
|
||||
{
|
||||
// at only works for objects
|
||||
if (JSON_HEDLEY_LIKELY(is_object()))
|
||||
@ -19358,7 +19375,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
}
|
||||
JSON_INTERNAL_CATCH (out_of_range&)
|
||||
{
|
||||
return default_value;
|
||||
return std::forward<ValueType>(default_value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -19553,15 +19570,24 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief remove element from a JSON object given a key
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/erase/
|
||||
size_type erase(const typename object_t::key_type& key)
|
||||
template < class KeyT, typename detail::enable_if_t <
|
||||
detail::is_usable_as_key_type<basic_json_t, KeyT>::value, int> = 0>
|
||||
size_type erase(const KeyT& key)
|
||||
{
|
||||
// this erase only works for objects
|
||||
if (JSON_HEDLEY_LIKELY(is_object()))
|
||||
if (JSON_HEDLEY_UNLIKELY(!is_object()))
|
||||
{
|
||||
return m_value.object->erase(key);
|
||||
JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
|
||||
}
|
||||
|
||||
JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
|
||||
const auto it = m_value.object->find(key);
|
||||
if (it != m_value.object->end())
|
||||
{
|
||||
m_value.object->erase(it);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// @brief remove element from a JSON array given an index
|
||||
@ -19596,14 +19622,15 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief find an element in a JSON object
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/find/
|
||||
template<typename KeyT>
|
||||
iterator find(KeyT&& key)
|
||||
template < class KeyT, typename detail::enable_if_t <
|
||||
detail::is_usable_as_key_type<basic_json_t, KeyT>::value, int> = 0>
|
||||
iterator find(const KeyT& key)
|
||||
{
|
||||
auto result = end();
|
||||
|
||||
if (is_object())
|
||||
{
|
||||
result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
|
||||
result.m_it.object_iterator = m_value.object->find(key);
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -19611,14 +19638,15 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief find an element in a JSON object
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/find/
|
||||
template<typename KeyT>
|
||||
const_iterator find(KeyT&& key) const
|
||||
template < class KeyT, typename detail::enable_if_t <
|
||||
detail::is_usable_as_key_type<basic_json_t, KeyT>::value, int> = 0>
|
||||
const_iterator find(const KeyT& key) const
|
||||
{
|
||||
auto result = cend();
|
||||
|
||||
if (is_object())
|
||||
{
|
||||
result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
|
||||
result.m_it.object_iterator = m_value.object->find(key);
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -19626,20 +19654,21 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
/// @brief returns the number of occurrences of a key in a JSON object
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/count/
|
||||
template<typename KeyT>
|
||||
size_type count(KeyT&& key) const
|
||||
template < class KeyT, typename detail::enable_if_t <
|
||||
detail::is_usable_as_key_type<basic_json_t, KeyT>::value, int> = 0>
|
||||
size_type count(const KeyT& key) const
|
||||
{
|
||||
// return 0 for all nonobject types
|
||||
return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
|
||||
return is_object() ? m_value.object->count(key) : 0;
|
||||
}
|
||||
|
||||
/// @brief check the existence of an element in a JSON object
|
||||
/// @sa https://json.nlohmann.me/api/basic_json/contains/
|
||||
template < typename KeyT, typename std::enable_if <
|
||||
!std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int >::type = 0 >
|
||||
bool contains(KeyT && key) const
|
||||
template < class KeyT, typename detail::enable_if_t <
|
||||
!std::is_same<typename std::decay<KeyT>::type, json_pointer>::value&& detail::is_usable_as_key_type<basic_json_t, KeyT>::value, int > = 0 >
|
||||
bool contains(const KeyT& key) const
|
||||
{
|
||||
return is_object() && m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
|
||||
return is_object() && m_value.object->find(key) != m_value.object->end();
|
||||
}
|
||||
|
||||
/// @brief check the existence of an element in a JSON object given a JSON pointer
|
||||
|
||||
Loading…
Reference in New Issue
Block a user