Skip to content

Commit c6ca564

Browse files
support std::string_view-convertible keys in operator[]
1 parent efa1fb3 commit c6ca564

File tree

2 files changed

+51
-1
lines changed

2 files changed

+51
-1
lines changed

include/nlohmann/detail/meta/type_traits.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -624,7 +624,11 @@ using is_usable_as_basic_json_key_type = typename std::conditional <
624624
is_usable_as_key_type<typename BasicJsonType::object_comparator_t,
625625
typename BasicJsonType::object_t::key_type, KeyTypeCVRef,
626626
RequireTransparentComparator, ExcludeObjectKeyType>::value
627-
&& !is_json_iterator_of<BasicJsonType, KeyType>::value,
627+
&& !is_json_iterator_of<BasicJsonType, KeyType>::value
628+
#ifdef JSON_HAS_CPP_17
629+
|| std::is_convertible<KeyType, std::string_view>::value
630+
#endif
631+
,
628632
std::true_type,
629633
std::false_type >::type;
630634

tests/src/unit-element_access2.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1790,3 +1790,49 @@ TEST_CASE_TEMPLATE("element access 2 (additional value() tests)", Json, nlohmann
17901790
#endif
17911791
}
17921792
}
1793+
1794+
1795+
#ifdef JSON_HAS_CPP_17
1796+
TEST_CASE("operator[] with user-defined std::string_view-convertible types")
1797+
{
1798+
using json = nlohmann::json;
1799+
1800+
class TestClass
1801+
{
1802+
std::string key_data_ = "foo";
1803+
public:
1804+
operator std::string_view() const { return key_data_; }
1805+
};
1806+
1807+
struct TestStruct
1808+
{
1809+
operator std::string_view() const { return "bar"; }
1810+
};
1811+
1812+
json j = { { "foo", "from_class" }, { "bar", "from_struct" } };
1813+
TestClass foo_obj;
1814+
TestStruct bar_obj;
1815+
1816+
SECTION("read access")
1817+
{
1818+
CHECK(j[foo_obj] == "from_class");
1819+
CHECK(j[TestClass{}] == "from_class");
1820+
CHECK(j[bar_obj] == "from_struct");
1821+
CHECK(j[TestStruct{}] == "from_struct");
1822+
}
1823+
1824+
SECTION("write access")
1825+
{
1826+
j[TestClass{}] = "updated_class";
1827+
j[TestStruct{}] = "updated_struct";
1828+
CHECK(j["foo"] == "updated_class");
1829+
CHECK(j["bar"] == "updated_struct");
1830+
1831+
SECTION("direct std::string_view access")
1832+
{
1833+
CHECK(j[std::string_view{"foo"}] == "updated_class");
1834+
CHECK(j[std::string_view{"bar"}] == "updated_struct");
1835+
}
1836+
}
1837+
}
1838+
#endif

0 commit comments

Comments
 (0)