Skip to content

Commit 2e6f761

Browse files
committed
Tests for StdAllocator.
1 parent 49e4dd6 commit 2e6f761

File tree

1 file changed

+165
-1
lines changed

1 file changed

+165
-1
lines changed

test/unittest/allocatorstest.cpp

Lines changed: 165 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616

1717
#include "rapidjson/allocators.h"
1818

19+
#include <string>
20+
#include <cstring>
21+
1922
using namespace rapidjson;
2023

2124
template <typename Allocator>
@@ -47,19 +50,180 @@ void TestAllocator(Allocator& a) {
4750
EXPECT_TRUE(a.Realloc(a.Malloc(1), 1, 0) == 0);
4851
}
4952

53+
struct TestStdAllocatorData {
54+
TestStdAllocatorData(int &constructions, int &destructions) :
55+
constructions_(&constructions),
56+
destructions_(&destructions)
57+
{
58+
++*constructions_;
59+
}
60+
TestStdAllocatorData(const TestStdAllocatorData& rhs) :
61+
constructions_(rhs.constructions_),
62+
destructions_(rhs.destructions_)
63+
{
64+
++*constructions_;
65+
}
66+
TestStdAllocatorData& operator=(const TestStdAllocatorData& rhs)
67+
{
68+
this->~TestStdAllocatorData();
69+
constructions_ = rhs.constructions_;
70+
destructions_ = rhs.destructions_;
71+
++*constructions_;
72+
return *this;
73+
}
74+
~TestStdAllocatorData()
75+
{
76+
++*destructions_;
77+
}
78+
private:
79+
TestStdAllocatorData();
80+
int *constructions_,
81+
*destructions_;
82+
};
83+
84+
template <typename Allocator>
85+
void TestStdAllocator(const Allocator& a) {
86+
typedef StdAllocator<void, Allocator> VoidAllocator;
87+
typedef typename VoidAllocator::template rebind<bool>::other BoolAllocator;
88+
BoolAllocator ba(a), ba2(a);
89+
EXPECT_TRUE(ba == ba2);
90+
EXPECT_FALSE(ba!= ba2);
91+
ba.deallocate(ba.allocate());
92+
EXPECT_TRUE(ba == ba2);
93+
EXPECT_FALSE(ba != ba2);
94+
95+
unsigned long long ll = 0, *llp = &ll;
96+
const unsigned long long cll = 0, *cllp = &cll;
97+
StdAllocator<unsigned long long, Allocator> lla(a);
98+
EXPECT_EQ(lla.address(ll), llp);
99+
EXPECT_EQ(lla.address(cll), cllp);
100+
EXPECT_TRUE(lla.max_size() > 0 && lla.max_size() <= SIZE_MAX / sizeof(unsigned long long));
101+
102+
int *arr;
103+
StdAllocator<int, Allocator> ia(a);
104+
arr = ia.allocate(10 * sizeof(int));
105+
EXPECT_TRUE(arr != 0);
106+
for (int i = 0; i < 10; ++i) {
107+
arr[i] = 0x0f0f0f0f;
108+
}
109+
ia.deallocate(arr, 10);
110+
arr = (int *)ia.Malloc(10 * sizeof(int));
111+
EXPECT_TRUE(arr != 0);
112+
for (int i = 0; i < 10; ++i) {
113+
arr[i] = 0x0f0f0f0f;
114+
}
115+
arr = (int *)ia.Realloc(arr, 10 * sizeof(int), 20 * sizeof(int));
116+
EXPECT_TRUE(arr != 0);
117+
for (int i = 0; i < 10; ++i) {
118+
EXPECT_EQ(arr[i], 0x0f0f0f0f);
119+
}
120+
for (int i = 10; i < 20; i++) {
121+
arr[i] = 0x0f0f0f0f;
122+
}
123+
ia.Free(arr);
124+
125+
int cons = 0, dest = 0;
126+
StdAllocator<TestStdAllocatorData, Allocator> da(a);
127+
for (int i = 1; i < 10; i++) {
128+
TestStdAllocatorData *d = da.allocate();
129+
EXPECT_TRUE(d != 0);
130+
131+
da.destroy(new(d) TestStdAllocatorData(cons, dest));
132+
EXPECT_EQ(cons, i);
133+
EXPECT_EQ(dest, i);
134+
135+
da.deallocate(d);
136+
}
137+
138+
typedef StdAllocator<char, Allocator> CharAllocator;
139+
typedef std::basic_string<char, std::char_traits<char>, CharAllocator> String;
140+
CharAllocator ca(a);
141+
String s(ca);
142+
for (int i = 0; i < 26; i++) {
143+
s.push_back(static_cast<char>('A' + i));
144+
}
145+
EXPECT_TRUE(s == "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
146+
}
147+
50148
TEST(Allocator, CrtAllocator) {
51149
CrtAllocator a;
150+
52151
TestAllocator(a);
152+
TestStdAllocator(a);
153+
154+
CrtAllocator a2;
155+
EXPECT_TRUE(a == a2);
156+
EXPECT_FALSE(a != a2);
157+
a2.Free(a2.Malloc(1));
158+
EXPECT_TRUE(a == a2);
159+
EXPECT_FALSE(a != a2);
53160
}
54161

55162
TEST(Allocator, MemoryPoolAllocator) {
56-
MemoryPoolAllocator<> a;
163+
const size_t capacity = RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY;
164+
MemoryPoolAllocator<> a(capacity);
165+
166+
a.Clear(); // noop
167+
EXPECT_EQ(a.Size(), 0u);
168+
EXPECT_EQ(a.Capacity(), 0u);
169+
EXPECT_EQ(a.Shared(), false);
170+
{
171+
MemoryPoolAllocator<> a2(a);
172+
EXPECT_EQ(a2.Shared(), true);
173+
EXPECT_EQ(a.Shared(), true);
174+
EXPECT_TRUE(a == a2);
175+
EXPECT_FALSE(a != a2);
176+
a2.Free(a2.Malloc(1));
177+
EXPECT_TRUE(a == a2);
178+
EXPECT_FALSE(a != a2);
179+
}
180+
EXPECT_EQ(a.Shared(), false);
181+
EXPECT_EQ(a.Capacity(), capacity);
182+
EXPECT_EQ(a.Size(), 8u); // aligned
183+
a.Clear();
184+
EXPECT_EQ(a.Capacity(), 0u);
185+
EXPECT_EQ(a.Size(), 0u);
186+
57187
TestAllocator(a);
188+
TestStdAllocator(a);
58189

59190
for (size_t i = 1; i < 1000; i++) {
60191
EXPECT_TRUE(a.Malloc(i) != 0);
61192
EXPECT_LE(a.Size(), a.Capacity());
62193
}
194+
195+
CrtAllocator baseAllocator;
196+
a = MemoryPoolAllocator<>(capacity, &baseAllocator);
197+
EXPECT_EQ(a.Capacity(), 0u);
198+
EXPECT_EQ(a.Size(), 0u);
199+
a.Free(a.Malloc(1));
200+
EXPECT_EQ(a.Capacity(), capacity);
201+
EXPECT_EQ(a.Size(), 8u); // aligned
202+
203+
{
204+
a.Clear();
205+
const size_t bufSize = 1024;
206+
char *buffer = (char *)a.Malloc(bufSize);
207+
MemoryPoolAllocator<> aligned_a(buffer, bufSize);
208+
EXPECT_TRUE(aligned_a.Capacity() > 0 && aligned_a.Capacity() <= bufSize);
209+
EXPECT_EQ(aligned_a.Size(), 0u);
210+
aligned_a.Free(aligned_a.Malloc(1));
211+
EXPECT_TRUE(aligned_a.Capacity() > 0 && aligned_a.Capacity() <= bufSize);
212+
EXPECT_EQ(aligned_a.Size(), 8u); // aligned
213+
}
214+
215+
{
216+
a.Clear();
217+
const size_t bufSize = 1024;
218+
char *buffer = (char *)a.Malloc(bufSize);
219+
RAPIDJSON_ASSERT(bufSize % sizeof(void*) == 0);
220+
MemoryPoolAllocator<> unaligned_a(buffer + 1, bufSize - 1);
221+
EXPECT_TRUE(unaligned_a.Capacity() > 0 && unaligned_a.Capacity() <= bufSize - sizeof(void*));
222+
EXPECT_EQ(unaligned_a.Size(), 0u);
223+
unaligned_a.Free(unaligned_a.Malloc(1));
224+
EXPECT_TRUE(unaligned_a.Capacity() > 0 && unaligned_a.Capacity() <= bufSize - sizeof(void*));
225+
EXPECT_EQ(unaligned_a.Size(), 8u); // aligned
226+
}
63227
}
64228

65229
TEST(Allocator, Alignment) {

0 commit comments

Comments
 (0)