Added move-constructor and move-assignment to BasicJsonDocument

This commit is contained in:
Benoit Blanchon
2020-03-01 17:24:29 +01:00
parent 2641697e0b
commit 2540b4e01b
5 changed files with 98 additions and 2 deletions

View File

@ -11,6 +11,7 @@ HEAD
* Fixed `MemberProxy::set(char[])` not duplicating the string (issue #1191) * Fixed `MemberProxy::set(char[])` not duplicating the string (issue #1191)
* Fixed enums serialized as booleans (issue #1197) * Fixed enums serialized as booleans (issue #1197)
* Fixed incorrect string comparison on some platforms (issue #1198) * Fixed incorrect string comparison on some platforms (issue #1198)
* Added move-constructor and move-assignment to `BasicJsonDocument`
v6.14.1 (2020-01-27) v6.14.1 (2020-01-27)
------- -------

View File

@ -8,6 +8,7 @@
#include <sstream> #include <sstream>
using ARDUINOJSON_NAMESPACE::addPadding; using ARDUINOJSON_NAMESPACE::addPadding;
using ARDUINOJSON_NAMESPACE::move;
class SpyingAllocator { class SpyingAllocator {
public: public:
@ -19,7 +20,7 @@ class SpyingAllocator {
return malloc(n); return malloc(n);
} }
void deallocate(void* p) { void deallocate(void* p) {
_log << "F"; _log << (p ? "F" : "f");
free(p); free(p);
} }
@ -43,8 +44,69 @@ TEST_CASE("BasicJsonDocument") {
{ {
MyJsonDocument doc1(4096, log); MyJsonDocument doc1(4096, log);
doc1.set(std::string("The size of this string is 32!!")); doc1.set(std::string("The size of this string is 32!!"));
MyJsonDocument doc2(doc1); MyJsonDocument doc2(doc1);
REQUIRE(doc1.as<std::string>() == "The size of this string is 32!!");
REQUIRE(doc2.as<std::string>() == "The size of this string is 32!!");
} }
REQUIRE(log.str() == "A4096A32FF"); REQUIRE(log.str() == "A4096A32FF");
} }
SECTION("Move construct") {
{
MyJsonDocument doc1(4096, log);
doc1.set(std::string("The size of this string is 32!!"));
MyJsonDocument doc2(move(doc1));
REQUIRE(doc2.as<std::string>() == "The size of this string is 32!!");
#if ARDUINOJSON_HAS_RVALUE_REFERENCES
REQUIRE(doc1.as<std::string>() == "null");
REQUIRE(doc1.capacity() == 0);
REQUIRE(doc2.capacity() == 4096);
#endif
}
#if ARDUINOJSON_HAS_RVALUE_REFERENCES
REQUIRE(log.str() == "A4096Ff");
#else
REQUIRE(log.str() == "A4096A32FF");
#endif
}
SECTION("Copy assign") {
{
MyJsonDocument doc1(4096, log);
doc1.set(std::string("The size of this string is 32!!"));
MyJsonDocument doc2(8, log);
doc2 = doc1;
REQUIRE(doc1.as<std::string>() == "The size of this string is 32!!");
REQUIRE(doc2.as<std::string>() == "The size of this string is 32!!");
}
REQUIRE(log.str() == "A4096A8FA32FF");
}
SECTION("Move assign") {
{
MyJsonDocument doc1(4096, log);
doc1.set(std::string("The size of this string is 32!!"));
MyJsonDocument doc2(8, log);
doc2 = move(doc1);
REQUIRE(doc2.as<std::string>() == "The size of this string is 32!!");
#if ARDUINOJSON_HAS_RVALUE_REFERENCES
REQUIRE(doc1.as<std::string>() == "null");
REQUIRE(doc1.capacity() == 0);
REQUIRE(doc2.capacity() == 4096);
#endif
}
#if ARDUINOJSON_HAS_RVALUE_REFERENCES
REQUIRE(log.str() == "A4096A8FFf");
#else
REQUIRE(log.str() == "A4096A8FA32FF");
#endif
}
} }

View File

@ -13,9 +13,11 @@
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
#define ARDUINOJSON_HAS_LONG_LONG 1 #define ARDUINOJSON_HAS_LONG_LONG 1
#define ARDUINOJSON_HAS_NULLPTR 1 #define ARDUINOJSON_HAS_NULLPTR 1
#define ARDUINOJSON_HAS_RVALUE_REFERENCES 1
#else #else
#define ARDUINOJSON_HAS_LONG_LONG 0 #define ARDUINOJSON_HAS_LONG_LONG 0
#define ARDUINOJSON_HAS_NULLPTR 0 #define ARDUINOJSON_HAS_NULLPTR 0
#define ARDUINOJSON_HAS_RVALUE_REFERENCES 0
#endif #endif
// Small or big machine? // Small or big machine?

View File

@ -52,6 +52,14 @@ class BasicJsonDocument : AllocatorOwner<TAllocator>, public JsonDocument {
set(src); set(src);
} }
#if ARDUINOJSON_HAS_RVALUE_REFERENCES
BasicJsonDocument(BasicJsonDocument&& src)
: AllocatorOwner<TAllocator>(src), JsonDocument(src) {
src._data.setNull();
src._pool = MemoryPool(0, 0);
}
#endif
// disambiguate // disambiguate
BasicJsonDocument(VariantRef src) BasicJsonDocument(VariantRef src)
: JsonDocument(allocPool(src.memoryUsage())) { : JsonDocument(allocPool(src.memoryUsage())) {
@ -68,6 +76,17 @@ class BasicJsonDocument : AllocatorOwner<TAllocator>, public JsonDocument {
return *this; return *this;
} }
#if ARDUINOJSON_HAS_RVALUE_REFERENCES
BasicJsonDocument& operator=(BasicJsonDocument&& src) {
freePool();
_data = src._data;
_pool = src._pool;
src._data.setNull();
src._pool = MemoryPool(0, 0);
return *this;
}
#endif
template <typename T> template <typename T>
BasicJsonDocument& operator=(const T& src) { BasicJsonDocument& operator=(const T& src) {
reallocPoolIfTooSmall(src.memoryUsage()); reallocPoolIfTooSmall(src.memoryUsage());

View File

@ -4,7 +4,7 @@
#pragma once #pragma once
#include <ArduinoJson/Namespace.hpp> #include "type_traits.hpp"
namespace ARDUINOJSON_NAMESPACE { namespace ARDUINOJSON_NAMESPACE {
template <typename T> template <typename T>
@ -13,4 +13,16 @@ inline void swap(T& a, T& b) {
a = b; a = b;
b = t; b = t;
} }
#if ARDUINOJSON_HAS_RVALUE_REFERENCES
template <typename T>
typename remove_reference<T>::type&& move(T&& t) {
return static_cast<typename remove_reference<T>::type&&>(t);
}
#else
template <typename T>
T& move(T& t) {
return t;
}
#endif
} // namespace ARDUINOJSON_NAMESPACE } // namespace ARDUINOJSON_NAMESPACE