36 using lib::test::showSizeof;
40 using std::numeric_limits;
53 const uint NUM_CLUSTERS = 5;
54 const uint NUM_TYPES = 20;
55 const uint NUM_OBJECTS = 500;
64 static_assert (0 < i);
65 array<uchar,i> content_;
71 checksum +=
explore(content_).resultSum();
76 checksum -=
explore(content_).resultSum();
79 uint getID() {
return content_[0]; }
91 inline array<function<void(AllocationCluster&, uchar)>, NUM_TYPES>
94 return { place_object<1>
120 auto invoker = buildTrampoline();
121 for (uint i=0; i<NUM_OBJECTS; ++i)
122 invoker[
rani (NUM_TYPES)] (clu, uchar(i));
158 CHECK (0 == clu.numExtents());
160 char c1(123), c2(45);
166 CHECK (1 ==ref1.getID());
167 CHECK (123==ref2.getID());
168 CHECK (45 ==ref3.getID());
170 CHECK (0 < clu.numExtents());
188 vector<AllocationCluster> clusters (NUM_CLUSTERS);
189 for (
auto& clu : clusters)
198 for (uint i=0; i<NUM_OBJECTS; ++i)
201 CHECK (clu.numExtents() == NUM_OBJECTS);
202 CHECK (checksum == NUM_OBJECTS * 223);
205 CHECK (allSum == checksum);
226 CHECK (0 == clu.numExtents());
228 CHECK (
nullptr == clu.storage_.pos);
229 CHECK ( 0 == clu.storage_.rest);
232 auto& i1 = clu.create<uint16_t> (1 + uint16_t(
rani()));
234 CHECK (1 == clu.numExtents());
236 CHECK (clu.storage_.pos !=
nullptr);
237 CHECK (clu.storage_.pos == (& i1) + 1 );
238 CHECK (clu.storage_.rest == EXTSIZ - (2*
sizeof(
void*) +
sizeof(uint16_t)));
241 byte* blk =
static_cast<std::byte*
>(clu.storage_.pos);
242 blk += clu.storage_.rest - EXTSIZ;
243 CHECK(
size_t(blk) <
size_t(clu.storage_.pos));
246 auto currBlock = [&]{
247 byte* blk =
static_cast<std::byte*
>(clu.storage_.pos);
248 blk += clu.storage_.rest - EXTSIZ;
251 auto posOffset = [&]{
252 return size_t(clu.storage_.pos) - size_t(currBlock());
254 auto slot = [&](
size_t i)
256 size_t* slot =
reinterpret_cast<size_t*
> (currBlock());
260 CHECK (blk == currBlock());
262 CHECK (posOffset() == 2 *
sizeof(
void*) +
sizeof(uint16_t));
263 CHECK (slot(0) == 0);
267 auto& i2 = clu.create<uint16_t> (55555);
268 CHECK (posOffset() == 2 *
sizeof(
void*) + 2 *
sizeof(uint16_t));
269 CHECK (clu.storage_.rest == EXTSIZ - posOffset());
273 CHECK (slot(0) == 0);
274 CHECK (slot(1) == 0);
277 char& c1 = clu.create<
char> (
'X');
278 CHECK (posOffset() == 2 *
sizeof(
void*) + 2 *
sizeof(uint16_t) +
sizeof(
char));
279 auto& i3 = clu.create<int32_t> (42);
280 CHECK (posOffset() == 2 *
sizeof(
void*) + 2 *
sizeof(uint16_t) +
sizeof(
char) + 3*
sizeof(byte) +
sizeof(int32_t));
285 CHECK (slot(0) == 0);
288 for (uint i=clu.storage_.rest; i>0; --i)
289 clu.create<uchar> (i);
290 CHECK (clu.storage_.rest == 0);
291 CHECK (posOffset() == EXTSIZ);
292 CHECK (clu.
numBytes() == EXTSIZ - 2*
sizeof(
void*));
293 CHECK (clu.numExtents() == 1);
294 CHECK (slot(0) == 0);
295 CHECK (blk == currBlock());
298 char& c2 = clu.create<
char> (
'U');
299 CHECK (blk != currBlock());
300 CHECK (getAdr(c2) == currBlock() + 2*
sizeof(
void*));
301 CHECK (clu.storage_.rest == EXTSIZ - posOffset());
302 CHECK (clu.
numBytes() == EXTSIZ - 2*
sizeof(
void*) + 1);
303 CHECK (clu.numExtents() == 2);
304 CHECK (slot(0) ==
size_t(blk));
312 size_t pp = posOffset();
313 auto& o1 = clu.createDisposable<
Dummy<2>> (4);
314 CHECK (o1.getID() == 4);
316 CHECK (checksum == 4+4);
317 CHECK (
alignof(
Dummy<2>) ==
alignof(
char));
318 CHECK (posOffset() - pp ==
sizeof(
Dummy<2>));
323 auto& o2 = clu.create<
Dummy<2>> (8);
324 CHECK (o2.getID() == 8);
325 CHECK (checksum == markSum + 8+8);
326 CHECK (posOffset() - pp >
sizeof(
Dummy<2>) + 2*
sizeof(
void*));
328 CHECK (
size_t(&o2) - slot(1) == 2*
sizeof(
void*));
330 auto dtor = (Dtor*)slot(1);
331 CHECK (dtor->next ==
nullptr);
336 string& s1 = clu.create<
string> (rands);
339 CHECK (posOffset() - pp >=
sizeof(
string) + 2*
sizeof(
void*));
340 CHECK (
size_t(&s1) - slot(1) == 2*
sizeof(
void*));
341 auto dtor2 = (Dtor*)slot(1);
342 CHECK (dtor2->next == dtor);
343 CHECK (dtor->next ==
nullptr);
349 CHECK (clu.numExtents() == 3);
350 CHECK (checksum == markSum + 8+8 + uchar(223*3));
351 auto dtor3 = (Dtor*)slot(1);
352 CHECK (dtor3->next ==
nullptr);
353 CHECK (dtor3 != dtor2);
354 CHECK (dtor2->next == dtor);
355 CHECK (dtor->next ==
nullptr);
363 CHECK (o1.getID() == 4);
364 CHECK (o2.getID() == 8);
365 CHECK (o3.getID() == 3);
367 CHECK (checksum == markSum);
386 using VecI = std::vector<uint16_t, Allo<uint16_t>>;
387 using Strg = std::basic_string<char, std::char_traits<char>,
Allo<char>>;
388 using SetS = std::set<Strg, std::less<Strg>,
Allo<Strg>>;
391 CHECK (clu.numExtents() == 0);
393 VecI vecI{clu.getAllocator<uint16_t>()};
401 for (uint i=1; i<=
MAX; ++i)
403 CHECK (clu.numExtents() == 2);
404 CHECK (vecI.capacity() == 64);
407 SetS setS{clu.getAllocator<Strg>()};
409 for (uint i=0; i<NUM_OBJECTS; ++i)
410 setS.emplace (test::randStr(32), clu.getAllocator<
char>());
411 CHECK (setS.size() > 0.9 * NUM_OBJECTS);
412 CHECK (clu.numExtents() > 200);
425 auto& l1 = clu.create<array<uchar,12>>();
426 CHECK (clu.numExtents() == 1);
429 auto& l2 = clu.create<array<uchar,5>>();
430 CHECK (clu.numExtents() == 1);
433 CHECK ( clu.canAdjust (&l2, 5, 8));
434 CHECK ( clu.canAdjust (&l2, 5, 5));
435 CHECK ( clu.canAdjust (&l2, 5, 2));
436 CHECK ( clu.canAdjust (&l2, 5, 0));
437 CHECK (not clu.canAdjust (&l1, 12,24));
438 CHECK (not clu.canAdjust (&l2, 6, 8));
439 CHECK (not clu.canAdjust (&l2, 4, 8));
440 CHECK (not clu.canAdjust (&l2, 5, 1000));
441 CHECK ( clu.canAdjust (&l1, 17,24));
443 CHECK (clu.numExtents() == 1);
454 using LERR_(INVALID);
457 CHECK (clu.numExtents() == 1);
462 CHECK (clu.numExtents() == 1);
465 CHECK (l1[11] == 11);
476 CHECK (clu.numExtents() == 1);
479 CHECK (l1[11] == 11);
static size_t constexpr EXTENT_SIZ
hard wired size of storage extents
auto explore(IT &&srcSeq)
start building a IterExplorer by suitably wrapping the given iterable source.
void doAdjust(void *loc, size_t oldSiz, size_t newSiz)
Adjust the size of the latest raw memory allocation dynamically.
Memory management for the low-level model (render nodes network).
int rani(uint bound=_iBOUND())
#define VERIFY_ERROR(ERROR_ID, ERRONEOUS_STATEMENT)
Macro to verify that a statement indeed raises an exception.
Helpers typically used while writing tests.
#define MAX(A, B)
the inevitable MAX macro, sometimes still necessary in template code
Implementation namespace for support and library code.
string randStr(size_t len)
create garbage string of given length
Simplistic test class runner.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
A collection of frequently used helper functions to support unit testing.
A Dummy object for tests.
A pile of objects sharing common allocation and lifecycle.
Building tree expanding and backtracking evaluations within hierarchical scopes.