// Copyright 2025 Steven Le Rouzic // // SPDX-License-Identifier: BSD-3-Clause #include "asl/testing/testing.hpp" #include "asl/tests/types.hpp" #include "asl/tests/counting_allocator.hpp" #include "asl/containers/chunked_buffer.hpp" static_assert(asl::moveable>); static_assert(asl::moveable>); static_assert(asl::moveable>); static_assert(asl::moveable>); static_assert(asl::copyable>); static_assert(asl::copyable>); static_assert(!asl::copyable>); static_assert(!asl::copyable>); ASL_TEST(reserve) { asl::chunked_buffer b; ASL_TEST_EXPECT(b.capacity() == 0); ASL_TEST_EXPECT(b.size() == 0); b.reserve_capacity(1); ASL_TEST_EXPECT(b.capacity() == 16); ASL_TEST_EXPECT(b.size() == 0); b.reserve_capacity(5); ASL_TEST_EXPECT(b.capacity() == 16); ASL_TEST_EXPECT(b.size() == 0); b.reserve_capacity(16); ASL_TEST_EXPECT(b.capacity() == 16); ASL_TEST_EXPECT(b.size() == 0); b.reserve_capacity(35); ASL_TEST_EXPECT(b.capacity() == 48); ASL_TEST_EXPECT(b.size() == 0); b.reserve_capacity(12); ASL_TEST_EXPECT(b.capacity() == 48); ASL_TEST_EXPECT(b.size() == 0); } ASL_TEST(resize_uninit) { asl::chunked_buffer b; ASL_TEST_EXPECT(b.capacity() == 0); ASL_TEST_EXPECT(b.size() == 0); b.resize_uninit(1); ASL_TEST_EXPECT(b.capacity() == 16); ASL_TEST_EXPECT(b.size() == 1); b.resize_uninit(5); ASL_TEST_EXPECT(b.capacity() == 16); ASL_TEST_EXPECT(b.size() == 5); b.resize_uninit(16); ASL_TEST_EXPECT(b.capacity() == 16); ASL_TEST_EXPECT(b.size() == 16); b.resize_uninit(35); ASL_TEST_EXPECT(b.capacity() == 48); ASL_TEST_EXPECT(b.size() == 35); b.resize_uninit(12); ASL_TEST_EXPECT(b.capacity() == 48); ASL_TEST_EXPECT(b.size() == 12); } ASL_TEST(resize_zero) { asl::chunked_buffer b; ASL_TEST_EXPECT(b.capacity() == 0); ASL_TEST_EXPECT(b.size() == 0); b.resize_zero(2); for (isize_t i = 0; i < 2; ++i) { ASL_TEST_EXPECT(b[i] == 0); } b.resize_zero(18); for (isize_t i = 0; i < 18; ++i) { ASL_TEST_EXPECT(b[i] == 0); } } ASL_TEST(resize) { asl::chunked_buffer b; ASL_TEST_EXPECT(b.capacity() == 0); ASL_TEST_EXPECT(b.size() == 0); b.resize(10); for (isize_t i = 0; i < 10; ++i) { ASL_TEST_EXPECT(b[i] == 0); } b.resize(20, 8); for (isize_t i = 0; i < 10; ++i) { ASL_TEST_EXPECT(b[i] == 0); } for (isize_t i = 10; i < 20; ++i) { ASL_TEST_EXPECT(b[i] == 8); } } ASL_TEST(push) { asl::chunked_buffer b; for (int i = 0; i < 100; ++i) { b.push(i); } for (int i = 0; i < 100; ++i) { ASL_TEST_EXPECT(b[i] == i); } b.resize(1000); for (int i = 0; i < 100; ++i) { ASL_TEST_EXPECT(b[i] == i); } } ASL_TEST(clear_destroy) { bool destroyed[5]{}; asl::chunked_buffer buf; for (bool& d: destroyed) { buf.push(&d); // NOLINT } for (const bool d: destroyed) { ASL_TEST_EXPECT(!d); } buf.clear(); for (const bool d: destroyed) { ASL_TEST_EXPECT(d); } } ASL_TEST(alloc_count) // NOLINT { CountingAllocator::Stats stats; asl::chunked_buffer buf{CountingAllocator{&stats}}; ASL_TEST_EXPECT(stats.alive_bytes == 0); ASL_TEST_EXPECT(stats.alloc_count == 0); ASL_TEST_EXPECT(stats.dealloc_count == 0); ASL_TEST_EXPECT(stats.any_alloc_count() == 0); buf.push(1); ASL_TEST_EXPECT(stats.alive_bytes > 0); ASL_TEST_EXPECT(stats.dealloc_count == 0); ASL_TEST_EXPECT(stats.any_alloc_count() == 1); buf.push(2); buf.push(3); buf.push(4); ASL_TEST_EXPECT(stats.alive_bytes > 0); ASL_TEST_EXPECT(stats.dealloc_count == 0); ASL_TEST_EXPECT(stats.any_alloc_count() == 1); buf.push(5); buf.push(6); ASL_TEST_EXPECT(stats.alive_bytes > 0); ASL_TEST_EXPECT(stats.dealloc_count == 0); ASL_TEST_EXPECT(stats.any_alloc_count() == 2); buf.resize(8, 8); ASL_TEST_EXPECT(stats.alive_bytes > 0); ASL_TEST_EXPECT(stats.dealloc_count == 0); ASL_TEST_EXPECT(stats.any_alloc_count() == 2); buf.resize(32, 8); ASL_TEST_EXPECT(stats.alive_bytes > 0); ASL_TEST_EXPECT(stats.dealloc_count == 0); ASL_TEST_EXPECT(stats.any_alloc_count() == 9); buf.resize(16, 0); ASL_TEST_EXPECT(stats.alive_bytes > 0); ASL_TEST_EXPECT(stats.dealloc_count == 0); ASL_TEST_EXPECT(stats.any_alloc_count() == 9); buf.clear(); ASL_TEST_EXPECT(stats.alive_bytes > 0); ASL_TEST_EXPECT(stats.dealloc_count == 0); ASL_TEST_EXPECT(stats.any_alloc_count() == 9); buf.destroy(); ASL_TEST_EXPECT(stats.alive_bytes == 0); ASL_TEST_EXPECT(stats.dealloc_count == 9); ASL_TEST_EXPECT(stats.any_alloc_count() == 9); } ASL_TEST(move) { bool destroyed[5]{}; { asl::chunked_buffer buf; for (bool& d: destroyed) { buf.push(&d); // NOLINT } for (const bool d: destroyed) { ASL_TEST_EXPECT(!d); } asl::chunked_buffer buf2 = std::move(buf); for (const bool d: destroyed) { ASL_TEST_EXPECT(!d); } buf = std::move(buf2); buf2.destroy(); for (const bool d: destroyed) { ASL_TEST_EXPECT(!d); } } for (const bool d: destroyed) { ASL_TEST_EXPECT(d); } } ASL_TEST(copy) // NOLINT { asl::chunked_buffer buf; for (int i = 0; i < 10; ++i) { buf.push(i); } asl::chunked_buffer buf2 = buf; ASL_TEST_EXPECT(buf.size() == 10); ASL_TEST_EXPECT(buf2.size() == 10); for (int i = 0; i < 10; ++i) { ASL_TEST_EXPECT(buf[i] == i); ASL_TEST_EXPECT(buf2[i] == i); } buf2.resize(5); buf = buf2; ASL_TEST_EXPECT(buf.size() == 5); ASL_TEST_EXPECT(buf2.size() == 5); for (int i = 0; i < 5; ++i) { ASL_TEST_EXPECT(buf[i] == i); ASL_TEST_EXPECT(buf2[i] == i); } buf.clear(); buf.resize(80, 12); buf2 = buf; ASL_TEST_EXPECT(buf.size() == 80); ASL_TEST_EXPECT(buf2.size() == 80); for (int i = 0; i < 80; ++i) { ASL_TEST_EXPECT(buf[i] == 12); ASL_TEST_EXPECT(buf2[i] == 12); } } ASL_TEST(iterator) { asl::chunked_buffer buf; for (int i = 0; i < 30; ++i) { buf.push(100 + i); } auto it = buf.begin(); auto end = buf.end(); for (int i = 0; i < 30; ++i) { ASL_TEST_ASSERT(it != end); ASL_TEST_EXPECT(*it == 100 + i); it++; } ASL_TEST_EXPECT(it == end); static_assert(asl::same_as); asl::chunked_buffer buf2; ASL_TEST_EXPECT(buf2.begin() == buf2.end()); } ASL_TEST(const_iterator) { asl::chunked_buffer buf_value; for (int i = 0; i < 30; ++i) { buf_value.push(100 + i); } const auto& buf = buf_value; auto it = buf.begin(); auto end = buf.end(); for (int i = 0; i < 30; ++i) { ASL_TEST_ASSERT(it != end); ASL_TEST_EXPECT(*it == 100 + i); ++it; } ASL_TEST_EXPECT(it == end); static_assert(asl::same_as); asl::chunked_buffer buf2; ASL_TEST_EXPECT(buf2.begin() == buf2.end()); }