support types convertible to string_view as JSON keys (#4958)

Signed-off-by: khloodelhossiny <khloood.elhossiny@gmail.com>
Co-authored-by: khloodelhossiny <khloood.elhossiny@gmail.com>
This commit is contained in:
KhloodElhossiny
2026-01-11 22:45:22 +02:00
committed by GitHub
parent 515d994acb
commit 8f75700141
3 changed files with 68 additions and 10 deletions

View File

@@ -636,11 +636,14 @@ using is_usable_as_key_type = typename std::conditional <
template<typename BasicJsonType, typename KeyTypeCVRef, bool RequireTransparentComparator = true,
bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>>
using is_usable_as_basic_json_key_type = typename std::conditional <
is_usable_as_key_type<typename BasicJsonType::object_comparator_t,
typename BasicJsonType::object_t::key_type, KeyTypeCVRef,
RequireTransparentComparator, ExcludeObjectKeyType>::value
&& !is_json_iterator_of<BasicJsonType, KeyType>::value,
std::true_type,
(is_usable_as_key_type<typename BasicJsonType::object_comparator_t,
typename BasicJsonType::object_t::key_type, KeyTypeCVRef,
RequireTransparentComparator, ExcludeObjectKeyType>::value
&& !is_json_iterator_of<BasicJsonType, KeyType>::value)
#ifdef JSON_HAS_CPP_17
|| std::is_convertible<KeyType, std::string_view>::value
#endif
, std::true_type,
std::false_type >::type;
template<typename ObjectType, typename KeyType>

View File

@@ -4180,11 +4180,14 @@ using is_usable_as_key_type = typename std::conditional <
template<typename BasicJsonType, typename KeyTypeCVRef, bool RequireTransparentComparator = true,
bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>>
using is_usable_as_basic_json_key_type = typename std::conditional <
is_usable_as_key_type<typename BasicJsonType::object_comparator_t,
typename BasicJsonType::object_t::key_type, KeyTypeCVRef,
RequireTransparentComparator, ExcludeObjectKeyType>::value
&& !is_json_iterator_of<BasicJsonType, KeyType>::value,
std::true_type,
(is_usable_as_key_type<typename BasicJsonType::object_comparator_t,
typename BasicJsonType::object_t::key_type, KeyTypeCVRef,
RequireTransparentComparator, ExcludeObjectKeyType>::value
&& !is_json_iterator_of<BasicJsonType, KeyType>::value)
#ifdef JSON_HAS_CPP_17
|| std::is_convertible<KeyType, std::string_view>::value
#endif
, std::true_type,
std::false_type >::type;
template<typename ObjectType, typename KeyType>

View File

@@ -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