diff --git a/CHANGELOG.md b/CHANGELOG.md index 37da05df..a62a3f9f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ HEAD ---- * Added `measureJson()` to the `ArduinoJson` namespace (PR #1069 by @nomis) +* Added support for `basic_string` (issue #1045) * Fixed example `JsonConfigFile.ino` for ESP8266 * Include `Arduino.h` if `ARDUINO` is defined (PR #1071 by @nomis) diff --git a/src/ArduinoJson/Serialization/DynamicStringWriter.hpp b/src/ArduinoJson/Serialization/DynamicStringWriter.hpp index ab10f49e..46e34550 100644 --- a/src/ArduinoJson/Serialization/DynamicStringWriter.hpp +++ b/src/ArduinoJson/Serialization/DynamicStringWriter.hpp @@ -54,13 +54,16 @@ class DynamicStringWriter { #endif #if ARDUINOJSON_ENABLE_STD_STRING -template <> -struct IsWriteableString : true_type {}; +template +struct IsWriteableString > + : true_type {}; + +template +class DynamicStringWriter > { + typedef std::basic_string string_type; -template <> -class DynamicStringWriter { public: - DynamicStringWriter(std::string &str) : _str(&str) {} + DynamicStringWriter(string_type &str) : _str(&str) {} size_t write(uint8_t c) { _str->operator+=(static_cast(c)); @@ -73,7 +76,7 @@ class DynamicStringWriter { } private: - std::string *_str; + string_type *_str; }; #endif } // namespace ARDUINOJSON_NAMESPACE diff --git a/src/ArduinoJson/Strings/StlStringAdapter.hpp b/src/ArduinoJson/Strings/StlStringAdapter.hpp index 1ec3e37d..fdbc8a5b 100644 --- a/src/ArduinoJson/Strings/StlStringAdapter.hpp +++ b/src/ArduinoJson/Strings/StlStringAdapter.hpp @@ -8,9 +8,10 @@ namespace ARDUINOJSON_NAMESPACE { +template class StlStringAdapter { public: - StlStringAdapter(const std::string& str) : _str(&str) {} + StlStringAdapter(const TString& str) : _str(&str) {} char* save(MemoryPool* pool) const { size_t n = _str->length() + 1; @@ -46,14 +47,18 @@ class StlStringAdapter { } private: - const std::string* _str; + const TString* _str; }; -template <> -struct IsString : true_type {}; +template +struct IsString > : true_type { +}; -inline StlStringAdapter adaptString(const std::string& str) { - return StlStringAdapter(str); +template +inline StlStringAdapter > +adaptString(const std::basic_string& str) { + return StlStringAdapter >( + str); } } // namespace ARDUINOJSON_NAMESPACE diff --git a/test/Misc/StringAdapters.cpp b/test/Misc/StringAdapters.cpp index aaee45f7..3cec005c 100644 --- a/test/Misc/StringAdapters.cpp +++ b/test/Misc/StringAdapters.cpp @@ -4,6 +4,7 @@ #include #include +#include "custom_string.hpp" using namespace ARDUINOJSON_NAMESPACE; @@ -31,9 +32,9 @@ TEST_CASE("ConstRamStringAdapter") { } } -TEST_CASE("StlString") { +TEST_CASE("std::string") { std::string str("bravo"); - StlStringAdapter adapter(str); + StlStringAdapter adapter = adaptString(str); REQUIRE(adapter.compare(NULL) > 0); REQUIRE(adapter.compare("alpha") > 0); @@ -43,3 +44,30 @@ TEST_CASE("StlString") { REQUIRE(adapter.equals("bravo")); REQUIRE_FALSE(adapter.equals("charlie")); } + +TEST_CASE("custom_string") { + custom_string str("bravo"); + StlStringAdapter adapter = adaptString(str); + + REQUIRE(adapter.compare(NULL) > 0); + REQUIRE(adapter.compare("alpha") > 0); + REQUIRE(adapter.compare("bravo") == 0); + REQUIRE(adapter.compare("charlie") < 0); + + REQUIRE(adapter.equals("bravo")); + REQUIRE_FALSE(adapter.equals("charlie")); +} + +TEST_CASE("IsString") { + SECTION("std::string") { + REQUIRE(IsString::value == true); + } + + SECTION("basic_string") { + REQUIRE(IsString >::value == false); + } + + SECTION("custom_string") { + REQUIRE(IsString::value == true); + } +} diff --git a/test/Misc/StringWriter.cpp b/test/Misc/StringWriter.cpp index 0e211ae7..2355984c 100644 --- a/test/Misc/StringWriter.cpp +++ b/test/Misc/StringWriter.cpp @@ -4,6 +4,7 @@ #include #include +#include "custom_string.hpp" using namespace ARDUINOJSON_NAMESPACE; @@ -48,8 +49,30 @@ TEST_CASE("StaticStringWriter") { } } -TEST_CASE("DynamicStringWriter") { +TEST_CASE("DynamicStringWriter") { std::string output; DynamicStringWriter sb(output); common_tests(sb, output); } + +TEST_CASE("DynamicStringWriter") { + custom_string output; + DynamicStringWriter sb(output); + + REQUIRE(4 == print(sb, "ABCD")); + REQUIRE("ABCD" == output); +} + +TEST_CASE("IsWriteableString") { + SECTION("std::string") { + REQUIRE(IsWriteableString::value == true); + } + + SECTION("custom_string") { + REQUIRE(IsWriteableString::value == true); + } + + SECTION("basic_string") { + REQUIRE(IsWriteableString >::value == false); + } +} diff --git a/test/Misc/custom_string.hpp b/test/Misc/custom_string.hpp new file mode 100644 index 00000000..cec838d2 --- /dev/null +++ b/test/Misc/custom_string.hpp @@ -0,0 +1,14 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2019 +// MIT License + +#pragma once + +#include + +using namespace ARDUINOJSON_NAMESPACE; + +struct custom_char_traits : std::char_traits {}; +struct custom_allocator : std::allocator {}; +typedef std::basic_string + custom_string;