Update to ArduinoJson 7.0.4
This commit is contained in:
25
lib/ArduinoJson/extras/tests/ResourceManager/CMakeLists.txt
Normal file
25
lib/ArduinoJson/extras/tests/ResourceManager/CMakeLists.txt
Normal file
@@ -0,0 +1,25 @@
|
||||
# ArduinoJson - https://arduinojson.org
|
||||
# Copyright © 2014-2024, Benoit BLANCHON
|
||||
# MIT License
|
||||
|
||||
add_executable(ResourceManagerTests
|
||||
allocVariant.cpp
|
||||
clear.cpp
|
||||
saveString.cpp
|
||||
shrinkToFit.cpp
|
||||
size.cpp
|
||||
StringBuilder.cpp
|
||||
swap.cpp
|
||||
)
|
||||
|
||||
add_compile_definitions(ResourceManagerTests
|
||||
ARDUINOJSON_SLOT_ID_SIZE=1 # require less RAM for overflow tests
|
||||
ARDUINOJSON_POOL_CAPACITY=16
|
||||
)
|
||||
|
||||
add_test(ResourceManager ResourceManagerTests)
|
||||
|
||||
set_tests_properties(ResourceManager
|
||||
PROPERTIES
|
||||
LABELS "Catch"
|
||||
)
|
||||
143
lib/ArduinoJson/extras/tests/ResourceManager/StringBuilder.cpp
Normal file
143
lib/ArduinoJson/extras/tests/ResourceManager/StringBuilder.cpp
Normal file
@@ -0,0 +1,143 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2024, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson/Memory/StringBuilder.hpp>
|
||||
#include <catch.hpp>
|
||||
|
||||
#include "Allocators.hpp"
|
||||
|
||||
using namespace ArduinoJson::detail;
|
||||
|
||||
TEST_CASE("StringBuilder") {
|
||||
KillswitchAllocator killswitch;
|
||||
SpyingAllocator spyingAllocator(&killswitch);
|
||||
ResourceManager resources(&spyingAllocator);
|
||||
|
||||
SECTION("Empty string") {
|
||||
StringBuilder str(&resources);
|
||||
|
||||
str.startString();
|
||||
str.save();
|
||||
|
||||
REQUIRE(resources.size() == sizeofString(""));
|
||||
REQUIRE(resources.overflowed() == false);
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog{
|
||||
Allocate(sizeofStringBuffer()),
|
||||
Reallocate(sizeofStringBuffer(), sizeofString("")),
|
||||
});
|
||||
}
|
||||
|
||||
SECTION("Short string fits in first allocation") {
|
||||
StringBuilder str(&resources);
|
||||
|
||||
str.startString();
|
||||
str.append("hello");
|
||||
|
||||
REQUIRE(str.isValid() == true);
|
||||
REQUIRE(str.str() == "hello");
|
||||
REQUIRE(resources.overflowed() == false);
|
||||
REQUIRE(spyingAllocator.log() == AllocatorLog{
|
||||
Allocate(sizeofStringBuffer()),
|
||||
});
|
||||
}
|
||||
|
||||
SECTION("Long string needs reallocation") {
|
||||
StringBuilder str(&resources);
|
||||
const char* lorem =
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do "
|
||||
"eiusmod tempor incididunt ut labore et dolore magna aliqua.";
|
||||
|
||||
str.startString();
|
||||
str.append(lorem);
|
||||
|
||||
REQUIRE(str.isValid() == true);
|
||||
REQUIRE(str.str() == lorem);
|
||||
REQUIRE(resources.overflowed() == false);
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog{
|
||||
Allocate(sizeofStringBuffer(1)),
|
||||
Reallocate(sizeofStringBuffer(1), sizeofStringBuffer(2)),
|
||||
Reallocate(sizeofStringBuffer(2), sizeofStringBuffer(3)),
|
||||
});
|
||||
}
|
||||
|
||||
SECTION("Realloc fails") {
|
||||
StringBuilder str(&resources);
|
||||
|
||||
str.startString();
|
||||
killswitch.on();
|
||||
str.append(
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do "
|
||||
"eiusmod tempor incididunt ut labore et dolore magna aliqua.");
|
||||
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog{
|
||||
Allocate(sizeofStringBuffer()),
|
||||
ReallocateFail(sizeofStringBuffer(), sizeofStringBuffer(2)),
|
||||
Deallocate(sizeofStringBuffer()),
|
||||
});
|
||||
REQUIRE(str.isValid() == false);
|
||||
REQUIRE(resources.overflowed() == true);
|
||||
}
|
||||
|
||||
SECTION("Initial allocation fails") {
|
||||
StringBuilder str(&resources);
|
||||
|
||||
killswitch.on();
|
||||
str.startString();
|
||||
|
||||
REQUIRE(str.isValid() == false);
|
||||
REQUIRE(resources.overflowed() == true);
|
||||
REQUIRE(spyingAllocator.log() == AllocatorLog{
|
||||
AllocateFail(sizeofStringBuffer()),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static StringNode* addStringToPool(ResourceManager& resources, const char* s) {
|
||||
StringBuilder str(&resources);
|
||||
str.startString();
|
||||
str.append(s);
|
||||
return str.save();
|
||||
}
|
||||
|
||||
TEST_CASE("StringBuilder::save() deduplicates strings") {
|
||||
ResourceManager resources;
|
||||
|
||||
SECTION("Basic") {
|
||||
auto s1 = addStringToPool(resources, "hello");
|
||||
auto s2 = addStringToPool(resources, "world");
|
||||
auto s3 = addStringToPool(resources, "hello");
|
||||
|
||||
REQUIRE(s1 == s3);
|
||||
REQUIRE(s2 != s3);
|
||||
REQUIRE(s1->references == 2);
|
||||
REQUIRE(s2->references == 1);
|
||||
REQUIRE(s3->references == 2);
|
||||
REQUIRE(resources.size() == sizeofString("hello") + sizeofString("world"));
|
||||
}
|
||||
|
||||
SECTION("Requires terminator") {
|
||||
auto s1 = addStringToPool(resources, "hello world");
|
||||
auto s2 = addStringToPool(resources, "hello");
|
||||
|
||||
REQUIRE(s2 != s1);
|
||||
REQUIRE(s1->references == 1);
|
||||
REQUIRE(s2->references == 1);
|
||||
REQUIRE(resources.size() ==
|
||||
sizeofString("hello world") + sizeofString("hello"));
|
||||
}
|
||||
|
||||
SECTION("Don't overrun") {
|
||||
auto s1 = addStringToPool(resources, "hello world");
|
||||
auto s2 = addStringToPool(resources, "wor");
|
||||
|
||||
REQUIRE(s2 != s1);
|
||||
REQUIRE(s1->references == 1);
|
||||
REQUIRE(s2->references == 1);
|
||||
REQUIRE(resources.size() ==
|
||||
sizeofString("hello world") + sizeofString("wor"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2024, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson/Memory/Alignment.hpp>
|
||||
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
||||
#include <ArduinoJson/Memory/VariantPoolImpl.hpp>
|
||||
#include <catch.hpp>
|
||||
|
||||
#include "Allocators.hpp"
|
||||
|
||||
using namespace ArduinoJson::detail;
|
||||
|
||||
TEST_CASE("ResourceManager::allocSlot()") {
|
||||
SECTION("Returns different pointer") {
|
||||
ResourceManager resources;
|
||||
|
||||
VariantSlot* s1 = resources.allocSlot();
|
||||
REQUIRE(s1 != 0);
|
||||
VariantSlot* s2 = resources.allocSlot();
|
||||
REQUIRE(s2 != 0);
|
||||
|
||||
REQUIRE(s1 != s2);
|
||||
}
|
||||
|
||||
SECTION("Returns the same slot after calling freeSlot()") {
|
||||
ResourceManager resources;
|
||||
|
||||
auto s1 = resources.allocSlot();
|
||||
auto s2 = resources.allocSlot();
|
||||
resources.freeSlot(s1);
|
||||
resources.freeSlot(s2);
|
||||
auto s3 = resources.allocSlot();
|
||||
auto s4 = resources.allocSlot();
|
||||
auto s5 = resources.allocSlot();
|
||||
|
||||
REQUIRE(s2.id() != s1.id());
|
||||
REQUIRE(s3.id() == s2.id());
|
||||
REQUIRE(s4.id() == s1.id());
|
||||
REQUIRE(s5.id() != s1.id());
|
||||
REQUIRE(s5.id() != s2.id());
|
||||
}
|
||||
|
||||
SECTION("Returns aligned pointers") {
|
||||
ResourceManager resources;
|
||||
|
||||
REQUIRE(isAligned(resources.allocSlot().operator VariantSlot*()));
|
||||
REQUIRE(isAligned(resources.allocSlot().operator VariantSlot*()));
|
||||
}
|
||||
|
||||
SECTION("Returns null if pool list allocation fails") {
|
||||
ResourceManager resources(FailingAllocator::instance());
|
||||
|
||||
auto variant = resources.allocSlot();
|
||||
REQUIRE(variant.id() == NULL_SLOT);
|
||||
REQUIRE(static_cast<VariantSlot*>(variant) == nullptr);
|
||||
}
|
||||
|
||||
SECTION("Returns null if pool allocation fails") {
|
||||
ResourceManager resources(FailingAllocator::instance());
|
||||
|
||||
resources.allocSlot();
|
||||
|
||||
auto variant = resources.allocSlot();
|
||||
REQUIRE(variant.id() == NULL_SLOT);
|
||||
REQUIRE(static_cast<VariantSlot*>(variant) == nullptr);
|
||||
}
|
||||
|
||||
SECTION("Try overflow pool counter") {
|
||||
ResourceManager resources;
|
||||
|
||||
// this test assumes SlotId is 8-bit; otherwise it consumes a lot of memory
|
||||
// tyhe GitHub Workflow gets killed
|
||||
REQUIRE(NULL_SLOT == 255);
|
||||
|
||||
// fill all the pools
|
||||
for (SlotId i = 0; i < NULL_SLOT; i++) {
|
||||
auto slot = resources.allocSlot();
|
||||
REQUIRE(slot.id() == i); // or != NULL_SLOT
|
||||
REQUIRE(static_cast<VariantSlot*>(slot) != nullptr);
|
||||
}
|
||||
|
||||
REQUIRE(resources.overflowed() == false);
|
||||
|
||||
// now all allocations should fail
|
||||
for (int i = 0; i < 10; i++) {
|
||||
auto slot = resources.allocSlot();
|
||||
REQUIRE(slot.id() == NULL_SLOT);
|
||||
REQUIRE(static_cast<VariantSlot*>(slot) == nullptr);
|
||||
}
|
||||
|
||||
REQUIRE(resources.overflowed() == true);
|
||||
}
|
||||
}
|
||||
30
lib/ArduinoJson/extras/tests/ResourceManager/clear.cpp
Normal file
30
lib/ArduinoJson/extras/tests/ResourceManager/clear.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2024, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
||||
#include <ArduinoJson/Memory/VariantPoolImpl.hpp>
|
||||
#include <ArduinoJson/Strings/StringAdapters.hpp>
|
||||
#include <catch.hpp>
|
||||
|
||||
using namespace ArduinoJson::detail;
|
||||
|
||||
TEST_CASE("ResourceManager::clear()") {
|
||||
ResourceManager resources;
|
||||
|
||||
SECTION("Discards allocated variants") {
|
||||
resources.allocSlot();
|
||||
|
||||
resources.clear();
|
||||
REQUIRE(resources.size() == 0);
|
||||
}
|
||||
|
||||
SECTION("Discards allocated strings") {
|
||||
resources.saveString(adaptString("123456789"));
|
||||
REQUIRE(resources.size() == sizeofString(9));
|
||||
|
||||
resources.clear();
|
||||
|
||||
REQUIRE(resources.size() == 0);
|
||||
}
|
||||
}
|
||||
70
lib/ArduinoJson/extras/tests/ResourceManager/saveString.cpp
Normal file
70
lib/ArduinoJson/extras/tests/ResourceManager/saveString.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2024, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
||||
#include <ArduinoJson/Strings/StringAdapters.hpp>
|
||||
#include <catch.hpp>
|
||||
|
||||
#include "Allocators.hpp"
|
||||
|
||||
using namespace ArduinoJson::detail;
|
||||
|
||||
static StringNode* saveString(ResourceManager& resources, const char* s) {
|
||||
return resources.saveString(adaptString(s));
|
||||
}
|
||||
|
||||
static StringNode* saveString(ResourceManager& resources, const char* s,
|
||||
size_t n) {
|
||||
return resources.saveString(adaptString(s, n));
|
||||
}
|
||||
|
||||
TEST_CASE("ResourceManager::saveString()") {
|
||||
ResourceManager resources;
|
||||
|
||||
SECTION("Duplicates different strings") {
|
||||
auto a = saveString(resources, "hello");
|
||||
auto b = saveString(resources, "world");
|
||||
REQUIRE(+a->data != +b->data);
|
||||
REQUIRE(a->length == 5);
|
||||
REQUIRE(b->length == 5);
|
||||
REQUIRE(a->references == 1);
|
||||
REQUIRE(b->references == 1);
|
||||
REQUIRE(resources.size() == sizeofString("hello") + sizeofString("world"));
|
||||
}
|
||||
|
||||
SECTION("Deduplicates identical strings") {
|
||||
auto a = saveString(resources, "hello");
|
||||
auto b = saveString(resources, "hello");
|
||||
REQUIRE(a == b);
|
||||
REQUIRE(a->length == 5);
|
||||
REQUIRE(a->references == 2);
|
||||
REQUIRE(resources.size() == sizeofString("hello"));
|
||||
}
|
||||
|
||||
SECTION("Deduplicates identical strings that contain NUL") {
|
||||
auto a = saveString(resources, "hello\0world", 11);
|
||||
auto b = saveString(resources, "hello\0world", 11);
|
||||
REQUIRE(a == b);
|
||||
REQUIRE(a->length == 11);
|
||||
REQUIRE(a->references == 2);
|
||||
REQUIRE(resources.size() == sizeofString("hello world"));
|
||||
}
|
||||
|
||||
SECTION("Don't stop on first NUL") {
|
||||
auto a = saveString(resources, "hello");
|
||||
auto b = saveString(resources, "hello\0world", 11);
|
||||
REQUIRE(a != b);
|
||||
REQUIRE(a->length == 5);
|
||||
REQUIRE(b->length == 11);
|
||||
REQUIRE(a->references == 1);
|
||||
REQUIRE(b->references == 1);
|
||||
REQUIRE(resources.size() ==
|
||||
sizeofString("hello") + sizeofString("hello world"));
|
||||
}
|
||||
|
||||
SECTION("Returns NULL when allocation fails") {
|
||||
ResourceManager pool2(FailingAllocator::instance());
|
||||
REQUIRE(saveString(pool2, "a") == nullptr);
|
||||
}
|
||||
}
|
||||
57
lib/ArduinoJson/extras/tests/ResourceManager/shrinkToFit.cpp
Normal file
57
lib/ArduinoJson/extras/tests/ResourceManager/shrinkToFit.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2024, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
||||
#include <ArduinoJson/Memory/VariantPoolImpl.hpp>
|
||||
#include <catch.hpp>
|
||||
|
||||
#include "Allocators.hpp"
|
||||
|
||||
using namespace ArduinoJson::detail;
|
||||
|
||||
TEST_CASE("ResourceManager::shrinkToFit()") {
|
||||
SpyingAllocator spyingAllocator;
|
||||
ResourceManager resources(&spyingAllocator);
|
||||
|
||||
SECTION("empty") {
|
||||
resources.shrinkToFit();
|
||||
|
||||
REQUIRE(spyingAllocator.log() == AllocatorLog{});
|
||||
}
|
||||
|
||||
SECTION("only one pool") {
|
||||
resources.allocSlot();
|
||||
|
||||
resources.shrinkToFit();
|
||||
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog{
|
||||
Allocate(sizeofPool()),
|
||||
Reallocate(sizeofPool(), sizeof(VariantSlot)),
|
||||
});
|
||||
}
|
||||
|
||||
SECTION("more pools than initial count") {
|
||||
for (size_t i = 0;
|
||||
i < ARDUINOJSON_POOL_CAPACITY * ARDUINOJSON_INITIAL_POOL_COUNT + 1;
|
||||
i++)
|
||||
resources.allocSlot();
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog{
|
||||
Allocate(sizeofPool()) * ARDUINOJSON_INITIAL_POOL_COUNT,
|
||||
Allocate(sizeofPoolList(ARDUINOJSON_INITIAL_POOL_COUNT * 2)),
|
||||
Allocate(sizeofPool()),
|
||||
});
|
||||
|
||||
spyingAllocator.clearLog();
|
||||
resources.shrinkToFit();
|
||||
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog{
|
||||
Reallocate(sizeofPool(), sizeof(VariantSlot)),
|
||||
Reallocate(sizeofPoolList(ARDUINOJSON_INITIAL_POOL_COUNT * 2),
|
||||
sizeofPoolList(ARDUINOJSON_INITIAL_POOL_COUNT + 1)),
|
||||
});
|
||||
}
|
||||
}
|
||||
31
lib/ArduinoJson/extras/tests/ResourceManager/size.cpp
Normal file
31
lib/ArduinoJson/extras/tests/ResourceManager/size.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2024, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
||||
#include <ArduinoJson/Memory/VariantPoolImpl.hpp>
|
||||
#include <catch.hpp>
|
||||
|
||||
#include "Allocators.hpp"
|
||||
|
||||
using namespace ArduinoJson::detail;
|
||||
|
||||
TEST_CASE("ResourceManager::size()") {
|
||||
TimebombAllocator timebomb(0);
|
||||
ResourceManager resources(&timebomb);
|
||||
|
||||
SECTION("Initial size is 0") {
|
||||
REQUIRE(0 == resources.size());
|
||||
}
|
||||
|
||||
SECTION("Doesn't grow when allocation of second pool fails") {
|
||||
timebomb.setCountdown(1);
|
||||
for (size_t i = 0; i < ARDUINOJSON_POOL_CAPACITY; i++)
|
||||
resources.allocSlot();
|
||||
size_t size = resources.size();
|
||||
|
||||
resources.allocSlot();
|
||||
|
||||
REQUIRE(size == resources.size());
|
||||
}
|
||||
}
|
||||
96
lib/ArduinoJson/extras/tests/ResourceManager/swap.cpp
Normal file
96
lib/ArduinoJson/extras/tests/ResourceManager/swap.cpp
Normal file
@@ -0,0 +1,96 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2024, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson/Memory/Alignment.hpp>
|
||||
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
||||
#include <ArduinoJson/Memory/VariantPoolImpl.hpp>
|
||||
#include <catch.hpp>
|
||||
|
||||
#include "Allocators.hpp"
|
||||
|
||||
using namespace ArduinoJson::detail;
|
||||
|
||||
static void fullPreallocatedPools(ResourceManager& resources) {
|
||||
for (int i = 0;
|
||||
i < ARDUINOJSON_INITIAL_POOL_COUNT * ARDUINOJSON_POOL_CAPACITY; i++)
|
||||
resources.allocSlot();
|
||||
}
|
||||
|
||||
TEST_CASE("ResourceManager::swap()") {
|
||||
SECTION("Both using preallocated pool list") {
|
||||
SpyingAllocator spy;
|
||||
ResourceManager a(&spy);
|
||||
ResourceManager b(&spy);
|
||||
|
||||
auto a1 = a.allocSlot();
|
||||
auto b1 = b.allocSlot();
|
||||
|
||||
swap(a, b);
|
||||
|
||||
REQUIRE(a1->data() == b.getSlot(a1.id())->data());
|
||||
REQUIRE(b1->data() == a.getSlot(b1.id())->data());
|
||||
|
||||
REQUIRE(spy.log() == AllocatorLog{
|
||||
Allocate(sizeofPool()) * 2,
|
||||
});
|
||||
}
|
||||
|
||||
SECTION("Only left using preallocated pool list") {
|
||||
SpyingAllocator spy;
|
||||
ResourceManager a(&spy);
|
||||
ResourceManager b(&spy);
|
||||
fullPreallocatedPools(b);
|
||||
|
||||
auto a1 = a.allocSlot();
|
||||
auto b1 = b.allocSlot();
|
||||
swap(a, b);
|
||||
|
||||
REQUIRE(a1->data() == b.getSlot(a1.id())->data());
|
||||
REQUIRE(b1->data() == a.getSlot(b1.id())->data());
|
||||
|
||||
REQUIRE(spy.log() ==
|
||||
AllocatorLog{
|
||||
Allocate(sizeofPool()) * (ARDUINOJSON_INITIAL_POOL_COUNT + 1),
|
||||
Allocate(sizeofPoolList(ARDUINOJSON_INITIAL_POOL_COUNT * 2)),
|
||||
Allocate(sizeofPool()),
|
||||
});
|
||||
}
|
||||
|
||||
SECTION("Only right using preallocated pool list") {
|
||||
SpyingAllocator spy;
|
||||
ResourceManager a(&spy);
|
||||
fullPreallocatedPools(a);
|
||||
ResourceManager b(&spy);
|
||||
|
||||
auto a1 = a.allocSlot();
|
||||
auto b1 = b.allocSlot();
|
||||
swap(a, b);
|
||||
|
||||
REQUIRE(a1->data() == b.getSlot(a1.id())->data());
|
||||
REQUIRE(b1->data() == a.getSlot(b1.id())->data());
|
||||
|
||||
REQUIRE(spy.log() ==
|
||||
AllocatorLog{
|
||||
Allocate(sizeofPool()) * ARDUINOJSON_INITIAL_POOL_COUNT,
|
||||
Allocate(sizeofPoolList(ARDUINOJSON_INITIAL_POOL_COUNT * 2)),
|
||||
Allocate(sizeofPool()) * 2,
|
||||
});
|
||||
}
|
||||
|
||||
SECTION("None is using preallocated pool list") {
|
||||
SpyingAllocator spy;
|
||||
ResourceManager a(&spy);
|
||||
fullPreallocatedPools(a);
|
||||
ResourceManager b(&spy);
|
||||
fullPreallocatedPools(b);
|
||||
|
||||
auto a1 = a.allocSlot();
|
||||
auto b1 = b.allocSlot();
|
||||
|
||||
swap(a, b);
|
||||
|
||||
REQUIRE(a1->data() == b.getSlot(a1.id())->data());
|
||||
REQUIRE(b1->data() == a.getSlot(b1.id())->data());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user