From 8f7570014107c5040103c5c4f9a55250be9add0c Mon Sep 17 00:00:00 2001 From: KhloodElhossiny <47139708+khloodelhossiny@users.noreply.github.com> Date: Sun, 11 Jan 2026 22:45:22 +0200 Subject: [PATCH] support types convertible to string_view as JSON keys (#4958) Signed-off-by: khloodelhossiny Co-authored-by: khloodelhossiny --- include/nlohmann/detail/meta/type_traits.hpp | 13 +++-- single_include/nlohmann/json.hpp | 13 +++-- tests/src/unit-element_access2.cpp | 52 ++++++++++++++++++++ 3 files changed, 68 insertions(+), 10 deletions(-) diff --git a/include/nlohmann/detail/meta/type_traits.hpp b/include/nlohmann/detail/meta/type_traits.hpp index 4a1f346f9..3299549fb 100644 --- a/include/nlohmann/detail/meta/type_traits.hpp +++ b/include/nlohmann/detail/meta/type_traits.hpp @@ -636,11 +636,14 @@ using is_usable_as_key_type = typename std::conditional < template> using is_usable_as_basic_json_key_type = typename std::conditional < - is_usable_as_key_type::value - && !is_json_iterator_of::value, - std::true_type, + (is_usable_as_key_type::value + && !is_json_iterator_of::value) +#ifdef JSON_HAS_CPP_17 + || std::is_convertible::value +#endif + , std::true_type, std::false_type >::type; template diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 3f154746c..27314f4b3 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -4180,11 +4180,14 @@ using is_usable_as_key_type = typename std::conditional < template> using is_usable_as_basic_json_key_type = typename std::conditional < - is_usable_as_key_type::value - && !is_json_iterator_of::value, - std::true_type, + (is_usable_as_key_type::value + && !is_json_iterator_of::value) +#ifdef JSON_HAS_CPP_17 + || std::is_convertible::value +#endif + , std::true_type, std::false_type >::type; template diff --git a/tests/src/unit-element_access2.cpp b/tests/src/unit-element_access2.cpp index 9097f4599..c4e25bf70 100644 --- a/tests/src/unit-element_access2.cpp +++ b/tests/src/unit-element_access2.cpp @@ -1790,3 +1790,55 @@ TEST_CASE_TEMPLATE("element access 2 (additional value() tests)", Json, nlohmann #endif } } + +#ifdef JSON_HAS_CPP_17 +TEST_CASE("operator[] with user-defined std::string_view-convertible types") +{ + using json = nlohmann::json; + + class TestClass + { + std::string key_data_ = "foo"; + + public: + operator std::string_view() const + { + return key_data_; + } + }; + + struct TestStruct + { + operator std::string_view() const + { + return "bar"; + } + }; + + json j = {{"foo", "from_class"}, {"bar", "from_struct"}}; + TestClass foo_obj; + TestStruct bar_obj; + + SECTION("read access") + { + CHECK(j[foo_obj] == "from_class"); + CHECK(j[TestClass{}] == "from_class"); + CHECK(j[bar_obj] == "from_struct"); + CHECK(j[TestStruct{}] == "from_struct"); + } + + SECTION("write access") + { + j[TestClass{}] = "updated_class"; + j[TestStruct{}] = "updated_struct"; + CHECK(j["foo"] == "updated_class"); + CHECK(j["bar"] == "updated_struct"); + + SECTION("direct std::string_view access") + { + CHECK(j[std::string_view{"foo"}] == "updated_class"); + CHECK(j[std::string_view{"bar"}] == "updated_struct"); + } + } +} +#endif