Skip to content

Commit f235157

Browse files
committed
Added support for std::string_view (closes #1578, closes #1554)
1 parent ba5cdab commit f235157

File tree

7 files changed

+181
-0
lines changed

7 files changed

+181
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ HEAD
99
* Fixed `serializeJson(doc, String)` when allocation fails (issue #1572)
1010
* Fixed clang-tidy warnings (issue #1574, PR #1577 by @armandas)
1111
* Added fake class `InvalidConversion<T1,T2>` to easily identify invalid conversions (issue #1585)
12+
* Added support for `std::string_view` (issue #1578, PR #1554 by @0xFEEDC0DE64)
1213

1314
v6.18.0 (2021-05-05)
1415
-------

extras/tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ link_libraries(ArduinoJson catch)
1111

1212
include_directories(Helpers)
1313
add_subdirectory(Cpp11)
14+
add_subdirectory(Cpp17)
1415
add_subdirectory(FailingBuilds)
1516
add_subdirectory(IntegrationTests)
1617
add_subdirectory(JsonArray)

extras/tests/Cpp17/CMakeLists.txt

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# ArduinoJson - https://arduinojson.org
2+
# Copyright Benoit Blanchon 2014-2021
3+
# MIT License
4+
5+
if(MSVC_VERSION LESS 1910)
6+
return()
7+
endif()
8+
9+
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5)
10+
return()
11+
endif()
12+
13+
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7)
14+
return()
15+
endif()
16+
17+
set(CMAKE_CXX_STANDARD 17)
18+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
19+
20+
add_executable(Cpp17Tests
21+
string_view.cpp
22+
)
23+
24+
add_test(Cpp17 Cpp17Tests)
25+
26+
set_tests_properties(Cpp17
27+
PROPERTIES
28+
LABELS "Catch"
29+
)

extras/tests/Cpp17/string_view.cpp

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#include <ArduinoJson.h>
2+
3+
#include <catch.hpp>
4+
#include <string_view>
5+
6+
#if !ARDUINOJSON_ENABLE_STRING_VIEW
7+
# error ARDUINOJSON_ENABLE_STRING_VIEW must be set to 1
8+
#endif
9+
10+
TEST_CASE("string_view") {
11+
StaticJsonDocument<128> doc;
12+
JsonVariant variant = doc.to<JsonVariant>();
13+
14+
SECTION("deserializeJson()") {
15+
auto err = deserializeJson(doc, std::string_view("123", 2));
16+
REQUIRE(err == DeserializationError::Ok);
17+
REQUIRE(doc.as<int>() == 12);
18+
}
19+
20+
SECTION("JsonDocument::set()") {
21+
doc.set(std::string_view("123", 2));
22+
REQUIRE(doc.as<std::string>() == "12");
23+
}
24+
25+
SECTION("JsonDocument::operator[]() const") {
26+
doc["ab"] = "Yes";
27+
doc["abc"] = "No";
28+
REQUIRE(doc[std::string_view("abc", 2)] == "Yes");
29+
}
30+
31+
SECTION("JsonDocument::operator[]()") {
32+
doc[std::string_view("abc", 2)] = "Yes";
33+
REQUIRE(doc["ab"] == "Yes");
34+
}
35+
36+
SECTION("JsonVariant::operator==()") {
37+
variant.set("A");
38+
REQUIRE(variant == std::string_view("AX", 1));
39+
REQUIRE_FALSE(variant == std::string_view("BX", 1));
40+
}
41+
42+
SECTION("JsonVariant::operator>()") {
43+
variant.set("B");
44+
REQUIRE(variant > std::string_view("AX", 1));
45+
REQUIRE_FALSE(variant > std::string_view("CX", 1));
46+
}
47+
48+
SECTION("JsonVariant::operator<()") {
49+
variant.set("B");
50+
REQUIRE(variant < std::string_view("CX", 1));
51+
REQUIRE_FALSE(variant < std::string_view("AX", 1));
52+
}
53+
54+
SECTION("String deduplication") {
55+
doc.add(std::string_view("example one", 7));
56+
REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(1) + 8);
57+
58+
doc.add(std::string_view("example two", 7));
59+
REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(2) + 8);
60+
}
61+
}
62+
63+
using ARDUINOJSON_NAMESPACE::adaptString;
64+
65+
TEST_CASE("StringViewAdapter") {
66+
std::string_view str("bravoXXX", 5);
67+
auto adapter = adaptString(str);
68+
69+
CHECK(adapter.compare(NULL) > 0);
70+
CHECK(adapter.compare("alpha") > 0);
71+
CHECK(adapter.compare("bravo") == 0);
72+
CHECK(adapter.compare("charlie") < 0);
73+
74+
CHECK(adapter.equals("bravo"));
75+
CHECK_FALSE(adapter.equals("charlie"));
76+
CHECK_FALSE(adapter.equals(NULL));
77+
78+
CHECK(adapter.size() == 5);
79+
}

src/ArduinoJson/Configuration.hpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,17 @@
6262
# endif
6363
#endif
6464

65+
#ifndef ARDUINOJSON_ENABLE_STRING_VIEW
66+
# ifdef __has_include
67+
# if __has_include(<string_view>) && __cplusplus >= 201703L
68+
# define ARDUINOJSON_ENABLE_STRING_VIEW 1
69+
# endif
70+
# endif
71+
#endif
72+
#ifndef ARDUINOJSON_ENABLE_STRING_VIEW
73+
# define ARDUINOJSON_ENABLE_STRING_VIEW 0
74+
#endif
75+
6576
#if ARDUINOJSON_EMBEDDED_MODE
6677

6778
// Store floats by default to reduce the memory usage (issue #134)

src/ArduinoJson/Strings/StringAdapters.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
# include <ArduinoJson/Strings/StdStringAdapter.hpp>
1313
#endif
1414

15+
#if ARDUINOJSON_ENABLE_STRING_VIEW
16+
# include <ArduinoJson/Strings/StringViewAdapter.hpp>
17+
#endif
18+
1519
#if ARDUINOJSON_ENABLE_ARDUINO_STRING
1620
# include <ArduinoJson/Strings/ArduinoStringAdapter.hpp>
1721
#endif
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// ArduinoJson - https://arduinojson.org
2+
// Copyright Benoit Blanchon 2014-2021
3+
// MIT License
4+
5+
#pragma once
6+
7+
#include <ArduinoJson/Namespace.hpp>
8+
#include <ArduinoJson/Strings/IsString.hpp>
9+
#include <ArduinoJson/Strings/StoragePolicy.hpp>
10+
11+
#include <string_view>
12+
13+
namespace ARDUINOJSON_NAMESPACE {
14+
15+
class StringViewAdapter {
16+
public:
17+
StringViewAdapter(std::string_view str) : _str(str) {}
18+
19+
void copyTo(char* p, size_t n) const {
20+
memcpy(p, _str.data(), n);
21+
}
22+
23+
bool isNull() const {
24+
return false;
25+
}
26+
27+
int compare(const char* other) const {
28+
if (!other)
29+
return 1;
30+
return _str.compare(other);
31+
}
32+
33+
bool equals(const char* expected) const {
34+
if (!expected)
35+
return false;
36+
return _str == expected;
37+
}
38+
39+
size_t size() const {
40+
return _str.size();
41+
}
42+
43+
typedef storage_policies::store_by_copy storage_policy;
44+
45+
private:
46+
std::string_view _str;
47+
};
48+
49+
template <>
50+
struct IsString<std::string_view> : true_type {};
51+
52+
inline StringViewAdapter adaptString(const std::string_view& str) {
53+
return StringViewAdapter(str);
54+
}
55+
56+
} // namespace ARDUINOJSON_NAMESPACE

0 commit comments

Comments
 (0)