|
JH-Toolkit v1.4.1
An engineering-oriented C++20 toolkit with duck-typed concepts, static design, async coroutines, and semantic containers — header-only, RTTI-free, and concurrency-friendly.
|
RAII-managed, non-resizable runtime array — a safe modern replacement for C99 VLA. More...
#include <cstdint>#include <vector>#include <span>#include <stdexcept>#include <cstring>#include <functional>#include <memory>#include <type_traits>#include "jh/conceptual/iterator.h"#include "jh/pods/pod_like.h"#include "jh/typing/monostate.h"#include "jh/macros/header_begin.h"#include "jh/macros/header_end.h"Go to the source code of this file.
Classes | |
| class | jh::runtime_arr< T, Alloc > |
| A move-only, fixed-capacity array with runtime-determined length and RAII-based ownership. More... | |
| struct | jh::runtime_arr< T, Alloc >::uninitialized_t |
| struct | jh::runtime_arr_helper::bool_flat_alloc |
Flat allocator for bool — disables bit-packing in jh::runtime_arr<bool>. More... | |
| struct | jh::runtime_arr_helper::bool_flat_alloc::rebind< U > |
| class | jh::runtime_arr< bool > |
Specialized implementation of jh::runtime_arr<bool> — a compact, bit-packed boolean array. More... | |
| struct | jh::runtime_arr< bool >::bit_ref |
| Internal reference proxy for single bit access. More... | |
| struct | jh::runtime_arr< bool >::bit_iterator |
| Iterator over individual bits in the bit-packed array. More... | |
| struct | jh::runtime_arr< bool >::bit_const_iterator |
| Const iterator over individual bits in the bit-packed array. More... | |
Namespaces | |
| namespace | jh::runtime_arr_helper |
Helper utilities and auxiliary types for jh::runtime_arr. | |
RAII-managed, non-resizable runtime array — a safe modern replacement for C99 VLA.
jh::runtime_arr<T, Alloc> provides a safe, RAII-managed version of the C99 Variable Length Array (VLA) concept, which was removed from C++ due to undefined behavior and stack safety concerns.
It represents a runtime-sized but fixed-capacity array with deterministic lifetime management — effectively combining the semantics of std::array (fixed capacity) with the flexibility of std::vector (runtime sizing), but without dynamic resizing.
std::span, ranges). reset_all()) and uninitialized construction paths. | Aspect | Behavior |
|---|---|
| Ownership | Unique / move-only (RAII semantics) |
| Resizability | ❌ — fixed-size only |
| Allocator | Optional (default: typed::monostate) |
| Initialization | Zero, uninitialized, or iterator-based |
| POD optimization | Automatic memset zeroing for POD-like types |
| Interop | STL-compatible iterators, std::span, view_interface |
| Feature | std::vector<T> | jh::runtime_arr<T> | std::array<T, N> | VLA (C99) |
|---|---|---|---|---|
| Compile-time size | ❌ | ❌ | ✅ | ❌ |
| Runtime size (fixed after init) | ✅ | ✅ (non-resizable) | ❌ | ✅ |
| Resizing / growth | ✅ | ❌ | ❌ | ❌ |
| Allocator control | ✅ (optional) | ✅ (optional) | ❌ | ❌ |
| Storage location | Heap | Heap (RAII-managed) | Stack / static | Stack (unsafe) |
| Exception safety | Strong | Strong (RAII + noexcept moves) | Strong | Undefined |
| POD zero-reset | ❌ | ✅ (reset_all()) | ❌ | ❌ |
| Lifetime management | Automatic (allocator) | RAII-owned unique_ptr | Automatic | Automatic (non-deterministic destruction) |
While C99 introduced Variable Length Arrays (VLAs) to allow runtime-sized stack arrays, they were banned in C++ due to undefined lifetime behavior, missing exception handling, and non-portable ABI implications.
jh::runtime_arr safely revives the same expressiveness using heap-based allocation, strong RAII ownership, and predictable lifetime management — without giving up performance or direct pointer interoperability.
runtime_arr<bool> — bit-packed specialization (64-bit words). set(), unset(), test(), reset_all() for bit control. data() and as_span() for safety. reset_all() to clear() for POD types. std::ranges::view_interface for range integration. unique_ptr<T[], deleter> (RAII). typed::monostate. reset_all() for POD/trivially destructible types. This header participates in the Dual-Mode Header system. You do not need to modify the source code to switch build modes:
jh-toolkit → behaves as a header-only component. jh-toolkit-static → uses the precompiled static implementation. The mode is resolved automatically through JH_INTERNAL_SHOULD_DEFINE, consistent with jh::immutable_str and other dual-mode headers (currently limited to immutable_str and runtime_arr in v1.3.x, but future releases may extend this system to additional components).
Microbenchmark results for jh::runtime_arr<T> (1024 POD elements, Apple Silicon M3, LLVM clang++ 20, 2025):
| Optimization Level | std::vector<T> | runtime_arr<T> | Relative Speedup |
|---|---|---|---|
| -O0 | ≈ 7.6 µs | ≈ 0.15 µs | ≈ 50× |
| -O2 | ≈ 0.13 µs | ≈ 0.017 µs | ≈ 7× |
| -O3 | ≈ 0.15 µs | ≈ 0.017 µs | ≈ 8× |
| -Ofast | ≈ 0.16 µs | ≈ 0.017 µs | ≈ 9× |
runtime_arr exhibits allocation cost virtually identical to raw operator new[]. -O2 upward, both std::vector and runtime_arr reach optimization saturation; higher levels (-O3, -Ofast) bring negligible gains. runtime_arr's simplified layout, absence of allocator_traits indirection, and elimination of dynamic capacity management. These results indicate that jh::runtime_arr offers stable, compiler-optimized, and allocation-efficient performance for fixed-size runtime buffers — matching the predictability of raw arrays while preserving RAII semantics and full STL interoperability.
1.4.1
2025