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.
Loading...
Searching...
No Matches
runtime_arr.h File Reference

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.

Detailed Description

RAII-managed, non-resizable runtime array — a safe modern replacement for C99 VLA.

Author
JeongHan-Bae <mastropseudo@gmail.com>

Overview

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.

Design Goals

  • Provide a safe, heap-based alternative to C99 VLAs with deterministic lifetime (RAII).
  • Offer predictable memory ownership and no implicit growth or reallocation.
  • Maintain contiguous memory layout and full STL interoperability (std::span, ranges).
  • Support POD-aware zeroing (reset_all()) and uninitialized construction paths.
  • Expose allocator parameterization for custom memory management, but default to safe local semantics.

Core Characteristics

AspectBehavior
OwnershipUnique / move-only (RAII semantics)
Resizability❌ — fixed-size only
AllocatorOptional (default: typed::monostate)
InitializationZero, uninitialized, or iterator-based
POD optimizationAutomatic memset zeroing for POD-like types
InteropSTL-compatible iterators, std::span, view_interface

Comparison vs Related Containers

Featurestd::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 locationHeapHeap
(RAII-managed)
Stack / staticStack (unsafe)
Exception safetyStrongStrong
(RAII + noexcept moves)
StrongUndefined
POD zero-reset✅ (reset_all())
Lifetime managementAutomatic (allocator)RAII-owned unique_ptrAutomaticAutomatic (non-deterministic destruction)

Design Motivation

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.

Specializations

  • runtime_arr<bool> — bit-packed specialization (64-bit words).
  • Provides set(), unset(), test(), reset_all() for bit control.
  • Explicitly disables data() and as_span() for safety.

Notes

  • No reallocation or growth semantics; all operations are in-place.
  • Prefer reset_all() to clear() for POD types.
  • Move-only by design — copying is deleted.
  • Ideal as a stable buffer for algorithms requiring strict capacity contracts.

Implementation Summary

  • Implements std::ranges::view_interface for range integration.
  • Backed by unique_ptr<T[], deleter> (RAII).
  • Allocator-aware; default uses typed::monostate.
  • Optimized reset_all() for POD/trivially destructible types.

Dual-Mode Header Integration

This header participates in the Dual-Mode Header system. You do not need to modify the source code to switch build modes:

  • When linked via jh-toolkit → behaves as a header-only component.
  • When linked via 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).

Performance Summary

Microbenchmark results for jh::runtime_arr<T> (1024 POD elements, Apple Silicon M3, LLVM clang++ 20, 2025):

Optimization Levelstd::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×

Observations

  • Benchmarks executed on Apple Silicon M3 using LLVM clang++ 20 (Darwin target).
  • For trivially constructible POD types, runtime_arr exhibits allocation cost virtually identical to raw operator new[].
  • From -O2 upward, both std::vector and runtime_arr reach optimization saturation; higher levels (-O3, -Ofast) bring negligible gains.
  • The consistent 6-9× advantage stems from runtime_arr's simplified layout, absence of allocator_traits indirection, and elimination of dynamic capacity management.
  • Measured variance < 1 % across runs, confirming deterministic RAII allocation and compiler inlining behavior.

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.

See also
jh::pod::pod_like
jh::typed::monostate
Version
1.4.1
Date
2025