at() for std::string_view #1529

parent ca9a1f2f
......@@ -3492,25 +3492,25 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
written using `at()`. It also demonstrates the different exceptions that
can be thrown.,at__object_t_key_type}
*/
reference at(const typename object_t::key_type& key)
template < class KeyType, typename std::enable_if <
#if defined(JSON_HAS_CPP_17)
std::is_same<KeyType, std::string_view>::value ||
#endif
std::is_convertible<KeyType, typename object_t::key_type>::value, int >::type = 0 >
reference at(const KeyType& key)
{
// at only works for objects
if (JSON_HEDLEY_LIKELY(is_object()))
if (JSON_HEDLEY_UNLIKELY(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));
}
JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
}
else
auto it = m_value.object->find(key);
if (it == m_value.object->end())
{
JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
JSON_THROW(out_of_range::create(403, "key '" + std::string(key) + "' not found", *this));
}
return set_parent(it->second);
}
/*!
......@@ -3543,25 +3543,25 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
`at()`. It also demonstrates the different exceptions that can be thrown.,
at__object_t_key_type_const}
*/
const_reference at(const typename object_t::key_type& key) const
template < class KeyType, typename std::enable_if <
#if defined(JSON_HAS_CPP_17)
std::is_same<KeyType, std::string_view>::value ||
#endif
std::is_convertible<KeyType, typename object_t::key_type>::value, int >::type = 0 >
const_reference at(const KeyType& key) const
{
// at only works for objects
if (JSON_HEDLEY_LIKELY(is_object()))
if (JSON_HEDLEY_UNLIKELY(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));
}
JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
}
else
auto it = m_value.object->find(key);
if (it == m_value.object->end())
{
JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
JSON_THROW(out_of_range::create(403, "key '" + std::string(key) + "' not found", *this));
}
return it->second;
}
/*!
......
......@@ -20305,25 +20305,25 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
written using `at()`. It also demonstrates the different exceptions that
can be thrown.,at__object_t_key_type}
*/
reference at(const typename object_t::key_type& key)
template < class KeyType, typename std::enable_if <
#if defined(JSON_HAS_CPP_17)
std::is_same<KeyType, std::string_view>::value ||
#endif
std::is_convertible<KeyType, typename object_t::key_type>::value, int >::type = 0 >
reference at(const KeyType& key)
{
// at only works for objects
if (JSON_HEDLEY_LIKELY(is_object()))
if (JSON_HEDLEY_UNLIKELY(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));
}
JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
}
else
auto it = m_value.object->find(key);
if (it == m_value.object->end())
{
JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
JSON_THROW(out_of_range::create(403, "key '" + std::string(key) + "' not found", *this));
}
return set_parent(it->second);
}
/*!
......@@ -20356,25 +20356,25 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
`at()`. It also demonstrates the different exceptions that can be thrown.,
at__object_t_key_type_const}
*/
const_reference at(const typename object_t::key_type& key) const
template < class KeyType, typename std::enable_if <
#if defined(JSON_HAS_CPP_17)
std::is_same<KeyType, std::string_view>::value ||
#endif
std::is_convertible<KeyType, typename object_t::key_type>::value, int >::type = 0 >
const_reference at(const KeyType& key) const
{
// at only works for objects
if (JSON_HEDLEY_LIKELY(is_object()))
if (JSON_HEDLEY_UNLIKELY(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));
}
JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
}
else
auto it = m_value.object->find(key);
if (it == m_value.object->end())
{
JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
JSON_THROW(out_of_range::create(403, "key '" + std::string(key) + "' not found", *this));
}
return it->second;
}
/*!
......
......@@ -32,6 +32,10 @@ SOFTWARE.
#include <nlohmann/json.hpp>
using nlohmann::json;
#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1)
#define JSON_HAS_CPP_17
#endif
TEST_CASE("element access 2")
{
SECTION("object")
......@@ -60,6 +64,26 @@ TEST_CASE("element access 2")
CHECK(j_const.at("floating") == json(42.23));
CHECK(j_const.at("object") == json::object());
CHECK(j_const.at("array") == json({1, 2, 3}));
#if defined(JSON_HAS_CPP_17)
CHECK(j.at(std::string_view("integer")) == json(1));
CHECK(j.at(std::string_view("unsigned")) == json(1u));
CHECK(j.at(std::string_view("boolean")) == json(true));
CHECK(j.at(std::string_view("null")) == json(nullptr));
CHECK(j.at(std::string_view("string")) == json("hello world"));
CHECK(j.at(std::string_view("floating")) == json(42.23));
CHECK(j.at(std::string_view("object")) == json::object());
CHECK(j.at(std::string_view("array")) == json({1, 2, 3}));
CHECK(j_const.at(std::string_view("integer")) == json(1));
CHECK(j_const.at(std::string_view("unsigned")) == json(1u));
CHECK(j_const.at(std::string_view("boolean")) == json(true));
CHECK(j_const.at(std::string_view("null")) == json(nullptr));
CHECK(j_const.at(std::string_view("string")) == json("hello world"));
CHECK(j_const.at(std::string_view("floating")) == json(42.23));
CHECK(j_const.at(std::string_view("object")) == json::object());
CHECK(j_const.at(std::string_view("array")) == json({1, 2, 3}));
#endif
}
SECTION("access outside bounds")
......@@ -1107,3 +1131,7 @@ TEST_CASE("element access 2 (throwing tests)")
}
}
#endif
#ifdef JSON_HAS_CPP_17
#undef JSON_HAS_CPP_17
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment