🚧 implement operator[] for string_view
This commit is contained in:
parent
4a78689865
commit
d42f37a5f8
@ -3667,7 +3667,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
In case the value was `null` before, it is converted to an object.
|
||||
|
||||
@param[in] key key of the element to access
|
||||
@tparam KeyT a type convertible to an object key or a `std::string_view`
|
||||
@tparam KeyT a type convertible to an object key, excluding `std::string_view`
|
||||
|
||||
@return reference to the element at key @a key
|
||||
|
||||
@ -3686,11 +3686,11 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
@since version 1.0.0
|
||||
*/
|
||||
template < class KeyT, typename std::enable_if <
|
||||
!std::is_same<typename std::decay<KeyT>::type, json_pointer>::value&& (
|
||||
!std::is_same<typename std::decay<KeyT>::type, json_pointer>::value&&
|
||||
#if defined(JSON_HAS_CPP_17)
|
||||
std::is_same<typename std::decay<KeyT>::type, std::string_view>::value ||
|
||||
!std::is_same<typename std::decay<KeyT>::type, std::string_view>::value&&
|
||||
#endif
|
||||
std::is_convertible<KeyT, typename object_t::key_type>::value), int >::type = 0 >
|
||||
std::is_convertible<KeyT, typename object_t::key_type>::value, int >::type = 0 >
|
||||
reference operator[](KeyT && key)
|
||||
{
|
||||
// implicitly convert null value to an empty object
|
||||
@ -3710,6 +3710,33 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
|
||||
}
|
||||
|
||||
#if defined(JSON_HAS_CPP_17)
|
||||
/// @copydoc operator[](KeyT&&)
|
||||
reference operator[](const std::string_view& key)
|
||||
{
|
||||
// implicitly convert null value to an empty object
|
||||
if (is_null())
|
||||
{
|
||||
m_type = value_t::object;
|
||||
m_value.object = create<object_t>();
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
// operator[] only works for objects
|
||||
if (JSON_HEDLEY_LIKELY(is_object()))
|
||||
{
|
||||
if (auto it = m_value.object->find(key); it != m_value.object->end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return set_parent(m_value.object->operator[](json::object_t::key_type(key)));
|
||||
}
|
||||
|
||||
JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
@brief read-only access specified object element
|
||||
|
||||
@ -3720,7 +3747,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
undefined.
|
||||
|
||||
@param[in] key key of the element to access
|
||||
@tparam KeyT a type convertible to an object key or a `std::string_view`
|
||||
@tparam KeyT a type convertible to an object key or, excluding `std::string_view`
|
||||
|
||||
@return const reference to the element at key @a key
|
||||
|
||||
@ -3742,11 +3769,11 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
@since version 1.0.0
|
||||
*/
|
||||
template < class KeyT, typename std::enable_if <
|
||||
!std::is_same<typename std::decay<KeyT>::type, json_pointer>::value&& (
|
||||
!std::is_same<typename std::decay<KeyT>::type, json_pointer>::value&&
|
||||
#if defined(JSON_HAS_CPP_17)
|
||||
std::is_same<typename std::decay<KeyT>::type, std::string_view>::value ||
|
||||
std::is_same<typename std::decay<KeyT>::type, std::string_view>::value&&
|
||||
#endif
|
||||
std::is_convertible<KeyT, typename object_t::key_type>::value), int >::type = 0 >
|
||||
std::is_convertible<KeyT, typename object_t::key_type>::value, int >::type = 0 >
|
||||
const_reference operator[](KeyT && key) const
|
||||
{
|
||||
// const operator[] only works for objects
|
||||
@ -3760,6 +3787,22 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
|
||||
}
|
||||
|
||||
#if defined(JSON_HAS_CPP_17)
|
||||
/// @copydoc operator[](KeyT&&) const
|
||||
const_reference operator[](const std::string_view& key) const
|
||||
{
|
||||
// operator[] only works for objects
|
||||
if (JSON_HEDLEY_LIKELY(is_object()))
|
||||
{
|
||||
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));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
@brief access specified object element
|
||||
|
||||
|
||||
@ -20556,7 +20556,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
In case the value was `null` before, it is converted to an object.
|
||||
|
||||
@param[in] key key of the element to access
|
||||
@tparam KeyT a type convertible to an object key or a `std::string_view`
|
||||
@tparam KeyT a type convertible to an object key, excluding `std::string_view`
|
||||
|
||||
@return reference to the element at key @a key
|
||||
|
||||
@ -20575,11 +20575,11 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
@since version 1.0.0
|
||||
*/
|
||||
template < class KeyT, typename std::enable_if <
|
||||
!std::is_same<typename std::decay<KeyT>::type, json_pointer>::value&& (
|
||||
!std::is_same<typename std::decay<KeyT>::type, json_pointer>::value&&
|
||||
#if defined(JSON_HAS_CPP_17)
|
||||
std::is_same<typename std::decay<KeyT>::type, std::string_view>::value ||
|
||||
!std::is_same<typename std::decay<KeyT>::type, std::string_view>::value&&
|
||||
#endif
|
||||
std::is_convertible<KeyT, typename object_t::key_type>::value), int >::type = 0 >
|
||||
std::is_convertible<KeyT, typename object_t::key_type>::value, int >::type = 0 >
|
||||
reference operator[](KeyT && key)
|
||||
{
|
||||
// implicitly convert null value to an empty object
|
||||
@ -20599,6 +20599,33 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
|
||||
}
|
||||
|
||||
#if defined(JSON_HAS_CPP_17)
|
||||
/// @copydoc operator[](KeyT&&)
|
||||
reference operator[](const std::string_view& key)
|
||||
{
|
||||
// implicitly convert null value to an empty object
|
||||
if (is_null())
|
||||
{
|
||||
m_type = value_t::object;
|
||||
m_value.object = create<object_t>();
|
||||
assert_invariant();
|
||||
}
|
||||
|
||||
// operator[] only works for objects
|
||||
if (JSON_HEDLEY_LIKELY(is_object()))
|
||||
{
|
||||
if (auto it = m_value.object->find(key); it != m_value.object->end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return set_parent(m_value.object->operator[](json::object_t::key_type(key)));
|
||||
}
|
||||
|
||||
JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
@brief read-only access specified object element
|
||||
|
||||
@ -20609,7 +20636,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
undefined.
|
||||
|
||||
@param[in] key key of the element to access
|
||||
@tparam KeyT a type convertible to an object key or a `std::string_view`
|
||||
@tparam KeyT a type convertible to an object key or, excluding `std::string_view`
|
||||
|
||||
@return const reference to the element at key @a key
|
||||
|
||||
@ -20631,11 +20658,11 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
@since version 1.0.0
|
||||
*/
|
||||
template < class KeyT, typename std::enable_if <
|
||||
!std::is_same<typename std::decay<KeyT>::type, json_pointer>::value&& (
|
||||
!std::is_same<typename std::decay<KeyT>::type, json_pointer>::value&&
|
||||
#if defined(JSON_HAS_CPP_17)
|
||||
std::is_same<typename std::decay<KeyT>::type, std::string_view>::value ||
|
||||
std::is_same<typename std::decay<KeyT>::type, std::string_view>::value&&
|
||||
#endif
|
||||
std::is_convertible<KeyT, typename object_t::key_type>::value), int >::type = 0 >
|
||||
std::is_convertible<KeyT, typename object_t::key_type>::value, int >::type = 0 >
|
||||
const_reference operator[](KeyT && key) const
|
||||
{
|
||||
// const operator[] only works for objects
|
||||
@ -20649,6 +20676,22 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
|
||||
}
|
||||
|
||||
#if defined(JSON_HAS_CPP_17)
|
||||
/// @copydoc operator[](KeyT&&) const
|
||||
const_reference operator[](const std::string_view& key) const
|
||||
{
|
||||
// operator[] only works for objects
|
||||
if (JSON_HEDLEY_LIKELY(is_object()))
|
||||
{
|
||||
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));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
@brief access specified object element
|
||||
|
||||
|
||||
@ -668,6 +668,56 @@ TEST_CASE("element access 2")
|
||||
CHECK(j_const[json::object_t::key_type("array")] == j["array"]);
|
||||
}
|
||||
|
||||
#ifdef JSON_HAS_CPP_17
|
||||
SECTION("access within bounds (string_view)")
|
||||
{
|
||||
CHECK(j["integer"] == json(1));
|
||||
CHECK(j[std::string_view("integer")] == j["integer"]);
|
||||
|
||||
CHECK(j["unsigned"] == json(1u));
|
||||
CHECK(j[std::string_view("unsigned")] == j["unsigned"]);
|
||||
|
||||
CHECK(j["boolean"] == json(true));
|
||||
CHECK(j[std::string_view("boolean")] == j["boolean"]);
|
||||
|
||||
CHECK(j["null"] == json(nullptr));
|
||||
CHECK(j[std::string_view("null")] == j["null"]);
|
||||
|
||||
CHECK(j["string"] == json("hello world"));
|
||||
CHECK(j[std::string_view("string")] == j["string"]);
|
||||
|
||||
CHECK(j["floating"] == json(42.23));
|
||||
CHECK(j[std::string_view("floating")] == j["floating"]);
|
||||
|
||||
CHECK(j["object"] == json::object());
|
||||
CHECK(j[std::string_view("object")] == j["object"]);
|
||||
|
||||
CHECK(j["array"] == json({1, 2, 3}));
|
||||
CHECK(j[std::string_view("array")] == j["array"]);
|
||||
|
||||
CHECK(j_const["integer"] == json(1));
|
||||
CHECK(j_const[std::string_view("integer")] == j["integer"]);
|
||||
|
||||
CHECK(j_const["boolean"] == json(true));
|
||||
CHECK(j_const[std::string_view("boolean")] == j["boolean"]);
|
||||
|
||||
CHECK(j_const["null"] == json(nullptr));
|
||||
CHECK(j_const[std::string_view("null")] == j["null"]);
|
||||
|
||||
CHECK(j_const["string"] == json("hello world"));
|
||||
CHECK(j_const[std::string_view("string")] == j["string"]);
|
||||
|
||||
CHECK(j_const["floating"] == json(42.23));
|
||||
CHECK(j_const[std::string_view("floating")] == j["floating"]);
|
||||
|
||||
CHECK(j_const["object"] == json::object());
|
||||
CHECK(j_const[std::string_view("object")] == j["object"]);
|
||||
|
||||
CHECK(j_const["array"] == json({1, 2, 3}));
|
||||
CHECK(j_const[std::string_view("array")] == j["array"]);
|
||||
}
|
||||
#endif
|
||||
|
||||
SECTION("access on non-object type")
|
||||
{
|
||||
SECTION("null")
|
||||
@ -683,6 +733,13 @@ TEST_CASE("element access 2")
|
||||
CHECK_THROWS_WITH(j_const_nonobject["foo"], "[json.exception.type_error.305] cannot use operator[] with a string argument with null");
|
||||
CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
|
||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with null");
|
||||
|
||||
#ifdef JSON_HAS_CPP_17
|
||||
CHECK_NOTHROW(j_nonobject2[std::string_view("foo")]);
|
||||
CHECK_THROWS_AS(j_const_nonobject[std::string_view("foo")], json::type_error&);
|
||||
CHECK_THROWS_WITH(j_const_nonobject[std::string_view("foo")],
|
||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with null");
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("boolean")
|
||||
@ -702,6 +759,15 @@ TEST_CASE("element access 2")
|
||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with boolean");
|
||||
CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
|
||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with boolean");
|
||||
|
||||
#ifdef JSON_HAS_CPP_17
|
||||
CHECK_THROWS_AS(j_nonobject[std::string_view("foo")], json::type_error&);
|
||||
CHECK_THROWS_WITH(j_nonobject[std::string_view("foo")],
|
||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with boolean");
|
||||
CHECK_THROWS_AS(j_const_nonobject[std::string_view("foo")], json::type_error&);
|
||||
CHECK_THROWS_WITH(j_const_nonobject[std::string_view("foo")],
|
||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with boolean");
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("string")
|
||||
@ -721,6 +787,15 @@ TEST_CASE("element access 2")
|
||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with string");
|
||||
CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
|
||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with string");
|
||||
|
||||
#ifdef JSON_HAS_CPP_17
|
||||
CHECK_THROWS_AS(j_nonobject[std::string_view("foo")], json::type_error&);
|
||||
CHECK_THROWS_WITH(j_nonobject[std::string_view("foo")],
|
||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with string");
|
||||
CHECK_THROWS_AS(j_const_nonobject[std::string_view("foo")], json::type_error&);
|
||||
CHECK_THROWS_WITH(j_const_nonobject[std::string_view("foo")],
|
||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with string");
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("array")
|
||||
@ -739,6 +814,15 @@ TEST_CASE("element access 2")
|
||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with array");
|
||||
CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
|
||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with array");
|
||||
|
||||
#ifdef JSON_HAS_CPP_17
|
||||
CHECK_THROWS_AS(j_nonobject[std::string_view("foo")], json::type_error&);
|
||||
CHECK_THROWS_WITH(j_nonobject[std::string_view("foo")],
|
||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with array");
|
||||
CHECK_THROWS_AS(j_const_nonobject[std::string_view("foo")], json::type_error&);
|
||||
CHECK_THROWS_WITH(j_const_nonobject[std::string_view("foo")],
|
||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with array");
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("number (integer)")
|
||||
@ -758,6 +842,15 @@ TEST_CASE("element access 2")
|
||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with number");
|
||||
CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
|
||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with number");
|
||||
|
||||
#ifdef JSON_HAS_CPP_17
|
||||
CHECK_THROWS_AS(j_nonobject[std::string_view("foo")], json::type_error&);
|
||||
CHECK_THROWS_WITH(j_nonobject[std::string_view("foo")],
|
||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with number");
|
||||
CHECK_THROWS_AS(j_const_nonobject[std::string_view("foo")], json::type_error&);
|
||||
CHECK_THROWS_WITH(j_const_nonobject[std::string_view("foo")],
|
||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with number");
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("number (unsigned)")
|
||||
@ -777,6 +870,15 @@ TEST_CASE("element access 2")
|
||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with number");
|
||||
CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
|
||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with number");
|
||||
|
||||
#ifdef JSON_HAS_CPP_17
|
||||
CHECK_THROWS_AS(j_nonobject[std::string_view("foo")], json::type_error&);
|
||||
CHECK_THROWS_WITH(j_nonobject[std::string_view("foo")],
|
||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with number");
|
||||
CHECK_THROWS_AS(j_const_nonobject[std::string_view("foo")], json::type_error&);
|
||||
CHECK_THROWS_WITH(j_const_nonobject[std::string_view("foo")],
|
||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with number");
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("number (floating-point)")
|
||||
@ -796,6 +898,15 @@ TEST_CASE("element access 2")
|
||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with number");
|
||||
CHECK_THROWS_WITH(j_const_nonobject[json::object_t::key_type("foo")],
|
||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with number");
|
||||
|
||||
#ifdef JSON_HAS_CPP_17
|
||||
CHECK_THROWS_AS(j_nonobject[std::string_view("foo")], json::type_error&);
|
||||
CHECK_THROWS_WITH(j_nonobject[std::string_view("foo")],
|
||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with number");
|
||||
CHECK_THROWS_AS(j_const_nonobject[std::string_view("foo")], json::type_error&);
|
||||
CHECK_THROWS_WITH(j_const_nonobject[std::string_view("foo")],
|
||||
"[json.exception.type_error.305] cannot use operator[] with a string argument with number");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user