Added support for basic_string<char, traits, allocator> (closes #1045)

This commit is contained in:
Benoit Blanchon
2019-08-12 14:21:45 +02:00
parent b9c4a0c5f6
commit 1e9cc285bb
6 changed files with 89 additions and 15 deletions

View File

@ -5,6 +5,7 @@ HEAD
----
* Added `measureJson()` to the `ArduinoJson` namespace (PR #1069 by @nomis)
* Added support for `basic_string<char, traits, allocator>` (issue #1045)
* Fixed example `JsonConfigFile.ino` for ESP8266
* Include `Arduino.h` if `ARDUINO` is defined (PR #1071 by @nomis)

View File

@ -54,13 +54,16 @@ class DynamicStringWriter<String> {
#endif
#if ARDUINOJSON_ENABLE_STD_STRING
template <>
struct IsWriteableString<std::string> : true_type {};
template <typename TCharTraits, typename TAllocator>
struct IsWriteableString<std::basic_string<char, TCharTraits, TAllocator> >
: true_type {};
template <typename TCharTraits, typename TAllocator>
class DynamicStringWriter<std::basic_string<char, TCharTraits, TAllocator> > {
typedef std::basic_string<char, TCharTraits, TAllocator> string_type;
template <>
class DynamicStringWriter<std::string> {
public:
DynamicStringWriter(std::string &str) : _str(&str) {}
DynamicStringWriter(string_type &str) : _str(&str) {}
size_t write(uint8_t c) {
_str->operator+=(static_cast<char>(c));
@ -73,7 +76,7 @@ class DynamicStringWriter<std::string> {
}
private:
std::string *_str;
string_type *_str;
};
#endif
} // namespace ARDUINOJSON_NAMESPACE

View File

@ -8,9 +8,10 @@
namespace ARDUINOJSON_NAMESPACE {
template <typename TString>
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<std::string> : true_type {};
template <typename TCharTraits, typename TAllocator>
struct IsString<std::basic_string<char, TCharTraits, TAllocator> > : true_type {
};
inline StlStringAdapter adaptString(const std::string& str) {
return StlStringAdapter(str);
template <typename TCharTraits, typename TAllocator>
inline StlStringAdapter<std::basic_string<char, TCharTraits, TAllocator> >
adaptString(const std::basic_string<char, TCharTraits, TAllocator>& str) {
return StlStringAdapter<std::basic_string<char, TCharTraits, TAllocator> >(
str);
}
} // namespace ARDUINOJSON_NAMESPACE

View File

@ -4,6 +4,7 @@
#include <ArduinoJson.h>
#include <catch.hpp>
#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<std::string> 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<custom_string> 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<T>") {
SECTION("std::string") {
REQUIRE(IsString<std::string>::value == true);
}
SECTION("basic_string<wchar_t>") {
REQUIRE(IsString<std::basic_string<wchar_t> >::value == false);
}
SECTION("custom_string") {
REQUIRE(IsString<custom_string>::value == true);
}
}

View File

@ -4,6 +4,7 @@
#include <ArduinoJson.h>
#include <catch.hpp>
#include "custom_string.hpp"
using namespace ARDUINOJSON_NAMESPACE;
@ -48,8 +49,30 @@ TEST_CASE("StaticStringWriter") {
}
}
TEST_CASE("DynamicStringWriter") {
TEST_CASE("DynamicStringWriter<std::string>") {
std::string output;
DynamicStringWriter<std::string> sb(output);
common_tests(sb, output);
}
TEST_CASE("DynamicStringWriter<custom_string>") {
custom_string output;
DynamicStringWriter<custom_string> sb(output);
REQUIRE(4 == print(sb, "ABCD"));
REQUIRE("ABCD" == output);
}
TEST_CASE("IsWriteableString") {
SECTION("std::string") {
REQUIRE(IsWriteableString<std::string>::value == true);
}
SECTION("custom_string") {
REQUIRE(IsWriteableString<custom_string>::value == true);
}
SECTION("basic_string<wchar_t>") {
REQUIRE(IsWriteableString<std::basic_string<wchar_t> >::value == false);
}
}

View File

@ -0,0 +1,14 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
#include <string>
using namespace ARDUINOJSON_NAMESPACE;
struct custom_char_traits : std::char_traits<char> {};
struct custom_allocator : std::allocator<char> {};
typedef std::basic_string<char, custom_char_traits, custom_allocator>
custom_string;