at() for std::string_view #1529

parent ca9a1f2f
...@@ -3492,25 +3492,25 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec ...@@ -3492,25 +3492,25 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
written using `at()`. It also demonstrates the different exceptions that written using `at()`. It also demonstrates the different exceptions that
can be thrown.,at__object_t_key_type} 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 // at only works for objects
if (JSON_HEDLEY_LIKELY(is_object())) if (JSON_HEDLEY_UNLIKELY(is_object()))
{ {
JSON_TRY JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
{
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
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 ...@@ -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()`. It also demonstrates the different exceptions that can be thrown.,
at__object_t_key_type_const} 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 // at only works for objects
if (JSON_HEDLEY_LIKELY(is_object())) if (JSON_HEDLEY_UNLIKELY(is_object()))
{ {
JSON_TRY JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
{
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
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 ...@@ -20305,25 +20305,25 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
written using `at()`. It also demonstrates the different exceptions that written using `at()`. It also demonstrates the different exceptions that
can be thrown.,at__object_t_key_type} 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 // at only works for objects
if (JSON_HEDLEY_LIKELY(is_object())) if (JSON_HEDLEY_UNLIKELY(is_object()))
{ {
JSON_TRY JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
{
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
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 ...@@ -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()`. It also demonstrates the different exceptions that can be thrown.,
at__object_t_key_type_const} 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 // at only works for objects
if (JSON_HEDLEY_LIKELY(is_object())) if (JSON_HEDLEY_UNLIKELY(is_object()))
{ {
JSON_TRY JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
{
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
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. ...@@ -32,6 +32,10 @@ SOFTWARE.
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
using nlohmann::json; 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") TEST_CASE("element access 2")
{ {
SECTION("object") SECTION("object")
...@@ -60,6 +64,26 @@ TEST_CASE("element access 2") ...@@ -60,6 +64,26 @@ TEST_CASE("element access 2")
CHECK(j_const.at("floating") == json(42.23)); CHECK(j_const.at("floating") == json(42.23));
CHECK(j_const.at("object") == json::object()); CHECK(j_const.at("object") == json::object());
CHECK(j_const.at("array") == json({1, 2, 3})); 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") SECTION("access outside bounds")
...@@ -1107,3 +1131,7 @@ TEST_CASE("element access 2 (throwing tests)") ...@@ -1107,3 +1131,7 @@ TEST_CASE("element access 2 (throwing tests)")
} }
} }
#endif #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