Add format utility

This commit is contained in:
2025-08-28 14:01:43 -04:00
parent 6fb57619c5
commit bc0d5a7422
5 changed files with 1306 additions and 1 deletions

View File

@@ -1,7 +1,9 @@
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include "arena_allocator.hpp"
#include "format.hpp"
#include <cstring>
#include <doctest/doctest.h>
#include <string>
#include <vector>
TEST_CASE("ArenaAllocator basic construction") {
@@ -532,3 +534,67 @@ TEST_CASE("ArenaAllocator realloc functionality") {
}
}
}
TEST_CASE("format function fallback codepath") {
SUBCASE("single-pass optimization success") {
ArenaAllocator arena(128);
auto result = format(arena, "Hello %s! Number: %d", "World", 42);
CHECK(result == "Hello World! Number: 42");
CHECK(result.length() == 23);
}
SUBCASE("fallback when speculative formatting fails") {
// Create arena with limited space to force fallback
ArenaAllocator arena(16);
// Consume most space to leave insufficient room for speculative formatting
arena.allocate<char>(10);
CHECK(arena.available_in_current_block() == 6);
// Format string larger than available space - should trigger fallback
std::string long_string = "This is a very long string that won't fit";
auto result = format(arena, "Prefix: %s with %d", long_string.c_str(), 123);
std::string expected =
"Prefix: This is a very long string that won't fit with 123";
CHECK(result == expected);
CHECK(result.length() == expected.length());
}
SUBCASE("edge case - exactly available space") {
ArenaAllocator arena(32);
arena.allocate<char>(20); // Leave 12 bytes
CHECK(arena.available_in_current_block() == 12);
// Format that needs exactly available space (should still use fallback due
// to null terminator)
auto result = format(arena, "Test%d", 123); // "Test123" = 7 chars
CHECK(result == "Test123");
CHECK(result.length() == 7);
}
SUBCASE("allocate_remaining_space postcondition") {
// Test empty arena
ArenaAllocator empty_arena(64);
auto space1 = empty_arena.allocate_remaining_space();
CHECK(space1.allocated_bytes >= 1);
CHECK(space1.allocated_bytes == 64);
// Test full arena (should create new block)
ArenaAllocator full_arena(32);
full_arena.allocate<char>(32); // Fill completely
auto space2 = full_arena.allocate_remaining_space();
CHECK(space2.allocated_bytes >= 1);
CHECK(space2.allocated_bytes == 32); // New block created
}
SUBCASE("format error handling") {
ArenaAllocator arena(64);
// Test with invalid format (should return empty string_view)
// Note: This is hard to trigger reliably across platforms,
// so we focus on successful cases in the other subcases
auto result = format(arena, "Valid format: %d", 42);
CHECK(result == "Valid format: 42");
}
}