From ca14e4bbfbd708d34fdcb426bec026eafb753b1e Mon Sep 17 00:00:00 2001 From: Igor Mineev Date: Fri, 9 Aug 2019 16:04:17 +0100 Subject: [PATCH 1/3] Add cxx17 string_view operator[] for Json::Value --- include/json/config.h | 2 ++ include/json/value.h | 2 ++ src/lib_json/json_value.cpp | 10 ++++++++++ 3 files changed, 14 insertions(+) diff --git a/include/json/config.h b/include/json/config.h index 6426c3b29..f772b938a 100644 --- a/include/json/config.h +++ b/include/json/config.h @@ -12,6 +12,7 @@ #include #include #include +#include #include /// If defined, indicates that json library is embedded in CppTL library. @@ -141,6 +142,7 @@ using Allocator = typename std::conditional, std::allocator>::type; using String = std::basic_string, Allocator>; +using StringView = std::basic_string_view>; using IStringStream = std::basic_istringstream; diff --git a/include/json/value.h b/include/json/value.h index a47884854..89db0eb58 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -464,6 +464,8 @@ class JSON_API Value { /// that name. /// \param key may contain embedded nulls. const Value& operator[](const String& key) const; + Value& operator[](const StringView key); + const Value& operator[](const StringView key) const; /** \brief Access an object value by name, create a null member if it does not * exist. * diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 6024212f2..ce48ce58a 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -1149,6 +1149,12 @@ Value const& Value::operator[](const String& key) const { return nullSingleton(); return *found; } +Value const& Value::operator[](const StringView key) const { + Value const* found = find(sv.data(), sv.data() + sv.length()); + if (!found) + return nullSingleton(); + return *found; +} Value& Value::operator[](const char* key) { return resolveReference(key, key + strlen(key)); @@ -1158,6 +1164,10 @@ Value& Value::operator[](const String& key) { return resolveReference(key.data(), key.data() + key.length()); } +Value& Value::operator[](const StringView key) { + return resolveReference(key.data(), key.data() + key.length()); +} + Value& Value::operator[](const StaticString& key) { return resolveReference(key.c_str()); } From 0f6b0a8ed51b1c629b0af74ce7e1e4d5ba235860 Mon Sep 17 00:00:00 2001 From: Igor Mineev Date: Fri, 9 Aug 2019 16:31:54 +0100 Subject: [PATCH 2/3] Add string_view Json::Value constructor --- include/json/value.h | 1 + src/lib_json/json_value.cpp | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/include/json/value.h b/include/json/value.h index 89db0eb58..5e727aa4f 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -325,6 +325,7 @@ class JSON_API Value { */ Value(const StaticString& value); Value(const String& value); + Value(const StringView value); #ifdef JSON_USE_CPPTL Value(const CppTL::ConstString& value); #endif diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index ce48ce58a..e5fab6b96 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -438,6 +438,12 @@ Value::Value(const String& value) { value.data(), static_cast(value.length())); } +Value::Value(const StringView value) { + initBasic(stringValue, true); + value_.string_ = duplicateAndPrefixStringValue( + value.data(), static_cast(value.length())); +} + Value::Value(const StaticString& value) { initBasic(stringValue); value_.string_ = const_cast(value.c_str()); From e7096b3ffcd8f7c251ec4830cf0e05ecec0289bf Mon Sep 17 00:00:00 2001 From: Igor Mineev Date: Tue, 13 Aug 2019 11:51:02 +0100 Subject: [PATCH 3/3] Add define for string_view. Add tests for string_view --- include/json/config.h | 8 +++++++- include/json/value.h | 6 ++++++ src/lib_json/json_value.cpp | 6 ++++++ src/test_lib_json/main.cpp | 12 ++++++++++++ 4 files changed, 31 insertions(+), 1 deletion(-) diff --git a/include/json/config.h b/include/json/config.h index f772b938a..b11fdbc39 100644 --- a/include/json/config.h +++ b/include/json/config.h @@ -12,9 +12,13 @@ #include #include #include -#include #include +#if __cplusplus >= 201703L +#include +#define JSON_USE_STRING_VIEW 1 +#endif + /// If defined, indicates that json library is embedded in CppTL library. //# define JSON_IN_CPPTL 1 @@ -142,7 +146,9 @@ using Allocator = typename std::conditional, std::allocator>::type; using String = std::basic_string, Allocator>; +#ifdef JSON_USE_STRING_VIEW using StringView = std::basic_string_view>; +#endif using IStringStream = std::basic_istringstream; diff --git a/include/json/value.h b/include/json/value.h index 5e727aa4f..41d09b564 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -325,7 +325,9 @@ class JSON_API Value { */ Value(const StaticString& value); Value(const String& value); +#ifdef JSON_USE_STRING_VIEW Value(const StringView value); +#endif #ifdef JSON_USE_CPPTL Value(const CppTL::ConstString& value); #endif @@ -465,8 +467,12 @@ class JSON_API Value { /// that name. /// \param key may contain embedded nulls. const Value& operator[](const String& key) const; + +#ifdef JSON_USE_STRING_VIEW Value& operator[](const StringView key); const Value& operator[](const StringView key) const; +#endif + /** \brief Access an object value by name, create a null member if it does not * exist. * diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index e5fab6b96..9e539e8e8 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -438,11 +438,13 @@ Value::Value(const String& value) { value.data(), static_cast(value.length())); } +#ifdef JSON_USE_STRING_VIEW Value::Value(const StringView value) { initBasic(stringValue, true); value_.string_ = duplicateAndPrefixStringValue( value.data(), static_cast(value.length())); } +#endif Value::Value(const StaticString& value) { initBasic(stringValue); @@ -1155,12 +1157,14 @@ Value const& Value::operator[](const String& key) const { return nullSingleton(); return *found; } +#ifdef JSON_USE_STRING_VIEW Value const& Value::operator[](const StringView key) const { Value const* found = find(sv.data(), sv.data() + sv.length()); if (!found) return nullSingleton(); return *found; } +#endif Value& Value::operator[](const char* key) { return resolveReference(key, key + strlen(key)); @@ -1170,9 +1174,11 @@ Value& Value::operator[](const String& key) { return resolveReference(key.data(), key.data() + key.length()); } +#ifdef JSON_USE_STRING_VIEW Value& Value::operator[](const StringView key) { return resolveReference(key.data(), key.data() + key.length()); } +#endif Value& Value::operator[](const StaticString& key) { return resolveReference(key.c_str()); diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index e700c3801..eb74b17b8 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -300,6 +300,18 @@ JSONTEST_FIXTURE(ValueTest, arrays) { JSONTEST_ASSERT_EQUAL(Json::Value(17), got); JSONTEST_ASSERT_EQUAL(false, array1_.removeIndex(2, &got)); // gone now } + +#ifdef JSON_USE_STRING_VIEW +JSONTEST_FIXTURE(ValueTest, stringView) { + Json::Value root; + Json::Value item("Test item"); + std::string_view sv = "array"; + std::string s = "array"; + root[s] = item; + JSONTEST_ASSERT_EQUAL(item.asString(), root[sv].asString()); +} +#endif + JSONTEST_FIXTURE(ValueTest, arrayIssue252) { int count = 5; Json::Value root;