Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions include/nlohmann/detail/meta/type_traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -621,11 +621,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>
Expand Down
13 changes: 8 additions & 5 deletions single_include/nlohmann/json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4164,11 +4164,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>
Expand Down
52 changes: 52 additions & 0 deletions tests/src/unit-element_access2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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