#include #include #include #include int main () { static u08 buffer[1024*1024]; static constexpr std::size_t alignment = 3; static constexpr std::size_t increment = 1; // ensure we have an base pointer that's off-by-one to a likely natural // system alignment u08* base = cruft::align::up ( std::data (buffer), alignof (std::max_align_t) ) + increment; cruft::alloc::aligned::foreign alloc ( cruft::view(base,std::end(buffer)), alignment ); cruft::TAP::logger tap; // ensure the first element allocated falls at the base address tap.expect_eq (base, alloc.data (), "allocator base address is the supplied base address"); tap.expect_eq (base, alloc.allocate (8).data (), "first allocation is the supplied base address"); // allocate a range of values and make sure they all satisfy our alignment. // don't choose values which are likely to combine with the testing // alignment to produce a likely system alignment. eg, 3 + 5 == 8 which is // a power-of-2. static const struct { size_t size; const char *message; } TESTS[] = { { 9, "just over a power of two" }, { 1, "a single byte" }, { 64, "a cache line" }, { 250, "multiple cache lines, but not a power of two" }, }; for (const auto &t: TESTS) { auto ptr = reinterpret_cast (alloc.allocate (t.size).data ()); auto offset = ptr - reinterpret_cast (base); tap.expect_mod (offset, alignment, "{:s}", t.message); } return tap.status (); };