Add documentation
This commit is contained in:
159
src/format.hpp
159
src/format.hpp
@@ -9,6 +9,90 @@
|
||||
|
||||
#include "arena_allocator.hpp"
|
||||
|
||||
/**
|
||||
* @brief Runtime printf-style formatting with arena allocation optimization.
|
||||
*
|
||||
* This function provides familiar printf-style formatting with intelligent
|
||||
* optimization for arena allocation. It attempts single-pass formatting by
|
||||
* speculatively using available arena space, falling back to two-pass
|
||||
* formatting only when necessary.
|
||||
*
|
||||
* The function uses an optimized allocation strategy:
|
||||
* 1. **Single-pass attempt**: Try to format directly into available arena space
|
||||
* 2. **Fallback to two-pass**: If formatting doesn't fit, measure required size
|
||||
* and allocate exactly what's needed
|
||||
*
|
||||
* ## Supported Format Specifiers:
|
||||
* All standard printf format specifiers are supported:
|
||||
* - **Integers**: %d, %i, %u, %x, %X, %o, %ld, %lld, etc.
|
||||
* - **Floating point**: %f, %e, %E, %g, %G, %.2f, etc.
|
||||
* - **Strings**: %s, %.*s, etc.
|
||||
* - **Characters**: %c
|
||||
* - **Pointers**: %p
|
||||
* - **Width/precision**: %10d, %-10s, %.2f, %*.*s, etc.
|
||||
*
|
||||
* ## Performance Characteristics:
|
||||
* - **Optimistic single-pass**: Often avoids the cost of measuring format size
|
||||
* - **Arena allocation**: Uses fast arena allocation (~1ns vs ~20-270ns for
|
||||
* malloc)
|
||||
* - **Memory efficient**: Returns unused space to arena via realloc()
|
||||
* - **Fallback safety**: Two-pass approach handles any format that doesn't fit
|
||||
*
|
||||
* @param arena Arena allocator for memory management
|
||||
* @param fmt Printf-style format string
|
||||
* @param ... Variable arguments matching format specifiers
|
||||
* @return std::string_view pointing to arena-allocated formatted string
|
||||
* @note Returns empty string_view on formatting errors
|
||||
* @note GCC format attribute enables compile-time format string validation
|
||||
*
|
||||
* ## Usage Examples:
|
||||
* ```cpp
|
||||
* ArenaAllocator arena(1024);
|
||||
*
|
||||
* // Basic formatting
|
||||
* auto msg = format(arena, "Hello %s!", "World");
|
||||
* // msg == "Hello World!"
|
||||
*
|
||||
* // Numeric formatting with precision
|
||||
* auto value = format(arena, "Pi: %.3f", 3.14159);
|
||||
* // value == "Pi: 3.142"
|
||||
*
|
||||
* // Mixed types with width/alignment
|
||||
* auto table = format(arena, "%-10s %5d %8.2f", "Item", 42, 99.95);
|
||||
* // table == "Item 42 99.95"
|
||||
*
|
||||
* // Error messages
|
||||
* auto error = format(arena, "Error %d: %s (line %d)", 404, "Not found", 123);
|
||||
* // error == "Error 404: Not found (line 123)"
|
||||
* ```
|
||||
*
|
||||
* ## When to Use:
|
||||
* - **Printf familiarity**: When you prefer printf-style format strings
|
||||
* - **Runtime flexibility**: Format strings from variables, config, or user
|
||||
* input
|
||||
* - **Complex formatting**: Precision, width, alignment, padding
|
||||
* - **Debugging**: Quick formatted output for logging/debugging
|
||||
* - **Mixed precision**: Different numeric precision requirements
|
||||
*
|
||||
* ## When to Use static_format() Instead:
|
||||
* - **Hot paths**: Performance-critical code where every nanosecond counts
|
||||
* - **Simple concatenation**: Basic string + number + string combinations
|
||||
* - **Compile-time optimization**: When all types/values known at compile time
|
||||
* - **Template contexts**: Where compile-time buffer sizing is beneficial
|
||||
*
|
||||
* ## Optimization Details:
|
||||
* The function uses `ArenaAllocator::allocate_remaining_space()` to claim all
|
||||
* available arena space and attempt formatting. If successful, it shrinks the
|
||||
* allocation to the actual size used. If formatting fails (doesn't fit), it
|
||||
* falls back to the traditional two-pass approach: measure size, allocate
|
||||
* exactly, then format.
|
||||
*
|
||||
* This strategy optimizes for the common case where available arena space is
|
||||
* sufficient, while maintaining correctness for all cases.
|
||||
*/
|
||||
std::string_view format(ArenaAllocator &arena, const char *fmt, ...)
|
||||
__attribute__((format(printf, 2, 3)));
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <int kLen> struct StringTerm {
|
||||
@@ -172,6 +256,76 @@ inline constexpr DoubleTerm term(double s) { return DoubleTerm(s); }
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/**
|
||||
* @brief Compile-time optimized formatting for high-performance code paths.
|
||||
*
|
||||
* This function provides ultra-fast string formatting by calculating buffer
|
||||
* sizes at compile time and using specialized term handlers for each type.
|
||||
* It's designed for performance-critical code where formatting overhead
|
||||
* matters.
|
||||
*
|
||||
* Unlike the runtime `format()` function, `static_format()` processes all
|
||||
* arguments at compile time to determine exact memory requirements and uses
|
||||
* optimized term writers for maximum speed.
|
||||
*
|
||||
* ## Supported Types:
|
||||
* - **String literals**: C-style string literals and arrays
|
||||
* - **Integers**: All integral types (int, int64_t, uint32_t, etc.)
|
||||
* - **Floating point**: double (uses high-precision Grisu2 algorithm)
|
||||
* - **Custom types**: Via specialization of `detail::term()`
|
||||
*
|
||||
* ## Performance Characteristics:
|
||||
* - **Compile-time buffer sizing**: Buffer size calculated at compile time (no
|
||||
* runtime measurement)
|
||||
* - **Optimized arena allocation**: Uses pre-calculated exact buffer sizes with
|
||||
* arena allocator
|
||||
* - **Specialized type handling**: Fast paths for common types via template
|
||||
* specialization
|
||||
* - **Memory efficient**: Uses arena.realloc() to return unused space to the
|
||||
* arena
|
||||
*
|
||||
* @tparam Ts Types of the arguments to format (auto-deduced)
|
||||
* @param arena Arena allocator for memory management
|
||||
* @param ts Arguments to format - can be string literals, integers, doubles
|
||||
* @return std::string_view pointing to arena-allocated formatted string
|
||||
*
|
||||
* ## Usage Examples:
|
||||
* ```cpp
|
||||
* ArenaAllocator arena(1024);
|
||||
*
|
||||
* // String concatenation
|
||||
* auto result1 = static_format(arena, "Hello ", "World", "!");
|
||||
* // result1 == "Hello World!"
|
||||
*
|
||||
* // Mixed types
|
||||
* auto result2 = static_format(arena, "Count: ", 42, ", Rate: ", 3.14);
|
||||
* // result2 == "Count: 42, Rate: 3.14"
|
||||
*
|
||||
* // Error messages
|
||||
* auto error = static_format(arena, "Error ", 404, ": ", "Not found");
|
||||
* // error == "Error 404: Not found"
|
||||
* ```
|
||||
*
|
||||
* ## When to Use:
|
||||
* - **Hot paths**: Performance-critical code where formatting speed matters
|
||||
* - **Known types**: When argument types are known at compile time
|
||||
* - **Simple formatting**: Concatenation and basic type conversion
|
||||
* - **Template code**: Where compile-time optimization is beneficial
|
||||
*
|
||||
* ## When to Use format() Instead:
|
||||
* - **Printf-style formatting**: When you need format specifiers like "%d",
|
||||
* "%.2f"
|
||||
* - **Runtime flexibility**: When format strings come from variables/config
|
||||
* - **Complex formatting**: When you need padding, precision, etc.
|
||||
* - **Convenience**: For quick debugging or non-critical paths
|
||||
*
|
||||
* @note All arguments are passed by forwarding reference for optimal
|
||||
* performance
|
||||
* @note Memory is arena-allocated and automatically sized to exact requirements
|
||||
* @note Compile-time errors occur if unsupported types are used
|
||||
* @note This function is constexpr-friendly and optimizes well in release
|
||||
* builds
|
||||
*/
|
||||
template <class... Ts>
|
||||
std::string_view static_format(ArenaAllocator &arena, Ts &&...ts) {
|
||||
constexpr int upper_bound =
|
||||
@@ -184,8 +338,3 @@ std::string_view static_format(ArenaAllocator &arena, Ts &&...ts) {
|
||||
arena.realloc(result, upper_bound, upper_bound - size),
|
||||
static_cast<std::size_t>(size));
|
||||
}
|
||||
|
||||
// Runtime formatting function using C-style varargs
|
||||
// For convenience in non-performance-critical code paths
|
||||
std::string_view format(ArenaAllocator &arena, const char *fmt, ...)
|
||||
__attribute__((format(printf, 2, 3)));
|
||||
|
||||
Reference in New Issue
Block a user