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
jh::runtime_arr< bool > Class Referencefinal

Specialized implementation of jh::runtime_arr<bool> — a compact, bit-packed boolean array. More...

#include <jh/core/runtime_arr.h>

Classes

struct  bit_ref
 Internal reference proxy for single bit access. More...
struct  bit_iterator
 Iterator over individual bits in the bit-packed array. More...
struct  bit_const_iterator
 Const iterator over individual bits in the bit-packed array. More...

Public Types

using raw_type = std::uint64_t
using value_type = bool
using size_type = std::uint64_t
using difference_type = std::ptrdiff_t
using reference = bit_ref
using const_reference = bool
using iterator = bit_iterator
using const_iterator = bit_const_iterator
using pointer
 Pointer type.
using const_pointer
 Const pointer type.
using allocator_type

Public Member Functions

 runtime_arr (std::uint64_t size)
 Constructs a bit-packed boolean runtime array with all bits zero-initialized.
 runtime_arr (std::vector< bool > &&vec)
 Constructs a bit-packed array by moving data from a std::vector<bool>.
 runtime_arr (std::initializer_list< bool > init)
 Constructs a bit-packed boolean runtime array from an initializer list.
template<typename ForwardIt>
requires (jh::concepts::forward_iterator<ForwardIt> && std::convertible_to<typename ForwardIt::value_type, value_type>)
 runtime_arr (ForwardIt first, ForwardIt last)
 Constructs a bit-packed array from a range of boolean values.
size_type size () const noexcept
 Returns the number of elements in the array.
bool empty () const noexcept
 Checks whether the array is empty.
raw_type * raw_data () noexcept
 Provides mutable access to the underlying word buffer.
const raw_type * raw_data () const noexcept
 Provides const access to the underlying word buffer.
size_type raw_word_count () const noexcept
 Returns the number of 64-bit words used internally to store all bits.
reference operator[] (std::uint64_t i) noexcept
 Unchecked bit access (read/write).
value_type operator[] (std::uint64_t i) const noexcept
 Unchecked const bit access (read-only).
reference at (std::uint64_t i)
 Bounds-checked bit access (read/write).
value_type at (std::uint64_t i) const
 Const bounds-checked bit access (read-only).
void set (std::uint64_t i, bool val=true)
 Sets or clears the bit at given index.
void unset (std::uint64_t i)
 Clears the bit at given index.
value_type test (std::uint64_t i) const
 Tests if the bit at index is set.
void reset_all () noexcept
 Resets all bits in the bit-packed array to zero.
 runtime_arr (runtime_arr &&other) noexcept
 Move constructor — transfers ownership of the bit-packed buffer.
runtime_arr< bool > & operator= (runtime_arr &&other) noexcept
 Move assignment operator — transfers ownership of the bit-packed buffer.
 operator std::vector< bool > () &&
 Converts the bit array into std::vector<bool>. Elements are copied bit-by-bit.
iterator begin () noexcept
 Mutable begin iterator over bits.
iterator end () noexcept
 Mutable end iterator over bits.
const_iterator begin () const noexcept
 Const begin iterator over bits.
const_iterator end () const noexcept
 Const end iterator over bits.
const_iterator cbegin () const noexcept
 Const begin iterator over bits.
const_iterator cend () const noexcept
 Const end iterator over bits.
void data () const =delete
 Deleted data() function — raw pointer access is not valid for bit-packed layout.
 runtime_arr (std::uint64_t size, auto)=delete
 Deleted allocator-based constructor.
std::span< value_type > as_span ()=delete
 Deleted — bit-packed array cannot expose a contiguous span of bools.
std::span< const value_type > as_span () const =delete
 Deleted — const version; contiguous view over bits is not representable.
 runtime_arr (const runtime_arr &)=delete
 Copy constructor deleted — bit array is non-copyable by design.
runtime_arroperator= (const runtime_arr &)=delete
 Copy assignment deleted — bit array is non-copyable by design.
 operator std::vector< bool > () &&
 Converts the array into a std::vector<T> by moving its contents.

Static Public Member Functions

static bool is_static_built ()

Static Public Attributes

static constexpr uninitialized_t uninitialized

Detailed Description

Specialized implementation of jh::runtime_arr<bool> — a compact, bit-packed boolean array.

Overview

This specialization provides a memory-efficient representation for bool values, storing them as individual bits within 64-bit words (uint64_t[]). Each bit represents a boolean value, achieving 8× memory compression compared to the generic runtime_arr<T, Alloc> template (which stores one byte per bool).

Its purpose is not raw speed but spatial density and fragmentation reduction — ideal for large logical masks, flags, and occupancy bitfields.

Relation to Generic Template

This specialization mirrors the structure of the generic runtime_arr<T, Alloc>, but modifies or disables certain operations that are incompatible with bit-level storage.

SemanticsGeneric MemberBool Specialization EquivalentNotes
Raw accessdata(), as_span()❌ DeletedDirect pointer access invalid for bit-packed layout.
Element accessoperator[](i)✅ ReimplementedNon-const returns bit_ref, const returns bool.
Bounded accessat(i)✅ ReimplementedSame proxy/value semantics with range checking.
Bulk resetreset_all()✅ ImplementedClears all bits via std::memset().
Bit manipulation(none)set(), unset(), test()New API for direct bit operations.
Allocator constructorruntime_arr(size, Alloc)❌ DeletedCustom allocators not supported for bit layout.
Copy semantics❌ Deleted❌ DeletedCopying disallowed to prevent shallow duplication.
Move semantics✅ Supported✅ SupportedSafe ownership transfer via RAII.

Core Characteristics

  • Stores bits compactly in 64-bit words (uint64_t[]).
  • Uses bit_ref proxies for writable element access.
  • Const accessors return plain bool values.
  • Implements bit_iterator for STL-style traversal.
  • Provides low-level access via raw_data() and raw_word_count().
  • Not a contiguous range (proxy elements are non-trivial).

Usage Guidance

This specialization is automatically selected when T == bool and the allocator parameter is omitted:

bits.set(3);
bits.unset(1);
bool b = bits.test(3);
A move-only, fixed-capacity array with runtime-determined length and RAII-based ownership.
Definition runtime_arr.h:367

To disable bit packing:

Use jh::runtime_arr<bool, jh::runtime_arr_helper::bool_flat_alloc> to obtain a byte-based layout (one byte per bool). This form is also the baseline used in all performance comparisons below.

plain[0] = true; // Stored as 1 byte per bool

Behavior Summary

AspectGeneric runtime_arr<T>Specialized runtime_arr<bool>
Storage layoutContiguous T[]Bit-packed (uint64_t[])
Element accessDirect referenceProxy (bit_ref) / value (bool)
data() / as_span()❌ Deleted
Allocator awareness❌ Deleted
Copy semantics
Move semantics
reset_all()Element-wise resetZero bits via memset()
Primary useGeneral runtime arrayCompact boolean bitset

Performance Characteristics

Microbenchmark results for jh::runtime_arr<bool> versus its byte-based counterpart jh::runtime_arr<bool, jh::runtime_arr_helper::bool_flat_alloc>, collected on Apple Silicon M3 with LLVM clang++ 20 (2025), under the following setup:

  • Array sizes: 1,024 and 1,000,000 elements
  • Bernoulli(0.5) data distribution
  • Catch2 microbenchmark harness
  • Single-threaded, in-cache workload
Empirical results
OptimizationN = 1,000,000 elementsN = 1,024 elements
set()read()reset_all()set()read()reset_all()
-O0~20× slower~2.8× slower~2.8× slower~0.3× faster~2.3× slower~2.3× slower
-O2~38× slower~160× slower~130× slower~0.55× faster~61× slower~60× slower
-O3~59× slower~140× slower~130× slower~0.6× faster~62× slower~61× slower
-Ofast~51× slower~150× slower~125× slower~0.5× faster~61× slower~59× slower
Interpretation
  • Small arrays (≤1K): Bit-packing may outperform byte-based storage in write-heavy scenarios due to 8× lower memory bandwidth usage. Reads and resets remain slower due to bit masking overhead.
  • Large arrays (≥1M): Bitwise access overhead dominates; set() is typically ~30-60× slower, and read() / reset_all() are ~120-160×± slower but mostly memory-bound.
  • Optimization scaling: -O2 already achieves full inlining; -O3 and -Ofast differences are within measurement noise (±2%).
  • Static instantiation: A precompiled specialization provides a debug fallback, mitigating -O0 template inlining overhead.

In summary, this specialization trades raw performance for memory compactness. It is most useful for boolean masks, sparse flags, and occupancy grids where space efficiency outweighs per-bit access cost.

Notes

  • Each bit resides in a 64-bit word.
  • Thread safety is not guaranteed for concurrent modification.
  • RAII-managed, deterministic destruction.
See also

Constructor & Destructor Documentation

◆ runtime_arr() [1/6]

jh::runtime_arr< bool >::runtime_arr ( std::uint64_t size)
explicit

Constructs a bit-packed boolean runtime array with all bits zero-initialized.

Parameters
sizeNumber of logical bits to allocate and initialize.

Behavior

  • Allocates ceil(size / 64) 64-bit words via new[].
  • All bits are cleared to zero (false).
  • Each bit is accessible through bit_ref proxy references.
  • Ownership is RAII-managed using std::unique_ptr<uint64_t[]>.
  • Allocator parameters are not supported for bit-packed storage.
Note

◆ runtime_arr() [2/6]

jh::runtime_arr< bool >::runtime_arr ( std::vector< bool > && vec)
explicit

Constructs a bit-packed array by moving data from a std::vector<bool>.

Parameters
vecRvalue reference to std::vector<bool> whose elements are copied bitwise.

Behavior

  • Allocates sufficient 64-bit words to store vec.size() bits.
  • Each element of vec is copied into the corresponding bit position.
  • Ownership and lifetime are RAII-managed internally.
  • The source vector remains valid but its contents are not preserved after the operation.
Note
  • Copying is bitwise; no shared memory with the original vector.
  • Move-only type — copy construction and assignment are deleted.

◆ runtime_arr() [3/6]

jh::runtime_arr< bool >::runtime_arr ( std::initializer_list< bool > init)

Constructs a bit-packed boolean runtime array from an initializer list.

Parameters
initInitializer list of boolean values.

Allocates the minimal number of 64-bit words required to represent all elements in init. Each bit is initialized according to the list values using set(i, v).

  • Storage is bit-packed: 64 elements per 64-bit word.
  • Managed via std::unique_ptr<uint64_t[]>.
  • Does not use allocators.
  • Move-only type; copy operations are deleted.
Exceptions
std::bad_allocIf allocation fails.

◆ runtime_arr() [4/6]

template<typename ForwardIt>
requires (jh::concepts::forward_iterator<ForwardIt> && std::convertible_to<typename ForwardIt::value_type, value_type>)
jh::runtime_arr< bool >::runtime_arr ( ForwardIt first,
ForwardIt last )
inline

Constructs a bit-packed array from a range of boolean values.

Template Parameters
ForwardItIterator type satisfying jh::concepts::forward_iterator.
Parameters
firstIterator to the start of the range.
lastIterator to the end of the range.
Exceptions
std::invalid_argumentIf the iterator range is invalid.

Behavior

  • Computes the number of elements using std::distance(first, last).
  • Allocates enough 64-bit words to store all bits.
  • Clears all bits to zero, then copies values from the input range bitwise.
  • Throws std::invalid_argument if the range length is negative.
Note
  • Supports any forward iterator, including container iterators and std::span.
  • Single-pass input iterators are not supported.
  • Resulting array is bit-packed and non-resizable.

◆ runtime_arr() [5/6]

jh::runtime_arr< bool >::runtime_arr ( runtime_arr< bool > && other)
noexcept

Move constructor — transfers ownership of the bit-packed buffer.

Behavior

  • Transfers ownership of the internal uint64_t[] buffer from other to *this.
  • After the move, other is left in an empty but valid state (size() == 0, raw_data() == nullptr).
  • No memory allocation or bit copy is performed — the operation is O(1).

Rationale

Move semantics allow efficient transfer of large bitsets across scopes, especially when benchmarking or composing higher-level containers. Copying remains disabled to avoid accidental deep duplication of bit-packed data.

◆ runtime_arr() [6/6]

jh::runtime_arr< bool >::runtime_arr ( std::uint64_t size,
auto  )
delete

Deleted allocator-based constructor.

Behavior

The runtime_arr<bool> specialization does not support allocator-based construction because its layout is bit-packed rather than byte-based. All allocation is performed internally via new[] with RAII management.

Note

Member Function Documentation

◆ at() [1/2]

reference jh::runtime_arr< bool >::at ( std::uint64_t i)

Bounds-checked bit access (read/write).

Returns a proxy reference to the bit at the specified index, performing explicit range checking. If i >= size(), an std::out_of_range exception is thrown.

Equivalent to operator[] but with explicit bounds validation. Mirrors the semantics of std::vector<bool>::at().

Parameters
iBit index within [0, size()).
Returns
Bit reference proxy representing the target bit.
Exceptions
std::out_of_rangeIf i >= size().
See also
operator[]()

◆ at() [2/2]

value_type jh::runtime_arr< bool >::at ( std::uint64_t i) const
nodiscard

Const bounds-checked bit access (read-only).

Returns the boolean value of the bit at the specified index, performing explicit range checking. If i >= size(), an std::out_of_range exception is thrown.

Mirrors std::vector<bool>::at() semantics — returning a plain bool rather than a proxy for const access.

Parameters
iBit index within [0, size()).
Returns
Boolean value of the bit.
Exceptions
std::out_of_rangeIf i >= size().
See also
operator[]()

◆ data()

void jh::runtime_arr< bool >::data ( ) const
delete

Deleted data() function — raw pointer access is not valid for bit-packed layout.

Behavior

  • This specialization intentionally deletes data() to prevent treating the bit-packed storage as a contiguous bool* array.
  • Internally, elements are stored as bits within 64-bit words, not as individual bytes.
Note
  • Use raw_data() and raw_word_count() to access the underlying uint64_t storage for low-level operations.
  • This deletion ensures type safety and prevents undefined behavior due to misaligned access.

◆ empty()

bool jh::runtime_arr< bool >::empty ( ) const
nodiscardnoexcept

Checks whether the array is empty.

Returns
true if size() == 0, otherwise false.

◆ operator std::vector< bool >() [1/2]

jh::runtime_arr< bool >::operator std::vector< bool > ( ) &&
explicit

Converts the bit array into std::vector<bool>. Elements are copied bit-by-bit.

Note
This operation consumes the array (clears and resets storage).

◆ operator std::vector< bool >() [2/2]

jh::runtime_arr< bool, typed::monostate >::operator std::vector< bool > ( ) &&
inlineexplicit

Converts the array into a std::vector<T> by moving its contents.

This conversion performs a one-way ownership transfer from runtime_arr<T> to std::vector<T>, consuming the source in the process. After the conversion, the original runtime_arr becomes an empty, valid but unspecified object (size() == 0, data() == nullptr).

Behavior

  • POD-like types (jh::pod_like<T>): Performs a raw std::memcpy for maximal performance. The operation is equivalent to copying a contiguous byte buffer.
  • Non-POD types: Uses std::make_move_iterator to move-construct each element into the target vector, ensuring proper object semantics.

Symmetry

This operator complements the constructor runtime_arr(std::vector<T>&&), enabling seamless two-way transfer between std::vector<T> and runtime_arr<T> with full move semantics. Both conversions leave the source container in a valid but empty state, ensuring safe RAII destruction.

Note
This operator is only available on rvalues (runtime_arr<T>&&), preventing accidental copies.
See also
runtime_arr(std::vector<T>&&)

◆ operator=()

runtime_arr< bool > & jh::runtime_arr< bool >::operator= ( runtime_arr< bool > && other)
noexcept

Move assignment operator — transfers ownership of the bit-packed buffer.

Behavior

  • Releases any existing owned buffer.
  • Takes ownership of other's bit-packed storage.
  • Leaves other empty and valid.
  • Performs no memory allocation or element-wise operation.
Note

This operator is noexcept and preserves RAII semantics. Copy assignment remains deleted to enforce unique ownership.

◆ operator[]() [1/2]

value_type jh::runtime_arr< bool >::operator[] ( std::uint64_t i) const
nodiscardnoexcept

Unchecked const bit access (read-only).

Provides read-only access to the bit at the specified index without bounds checking (undefined behavior if out of range). Returns the boolean value corresponding to the bit's state.

Parameters
iBit index within [0, size()).
Returns
Boolean value of the bit.

◆ operator[]() [2/2]

reference jh::runtime_arr< bool >::operator[] ( std::uint64_t i)
noexcept

Unchecked bit access (read/write).

Returns a proxy reference to the bit at the specified index without performing bounds checking (undefined behavior if out of range). Equivalent to *(data() + index) in semantics, but operates on a bit-packed storage layout.

Parameters
iBit index within [0, size()).
Returns
Reference proxy object representing the targeted bit.

◆ raw_data() [1/2]

const raw_type * jh::runtime_arr< bool >::raw_data ( ) const
nodiscardnoexcept

Provides const access to the underlying word buffer.

Behavior

  • Returns a const pointer to the uint64_t buffer.
  • Useful for inspection or bitwise read-only operations.
Note
  • Equivalent to the mutable form, but guarantees const-correct access.
  • Replaces const data() from the generic runtime_arr<T> template.

◆ raw_data() [2/2]

raw_type * jh::runtime_arr< bool >::raw_data ( )
noexcept

Provides mutable access to the underlying word buffer.

Behavior

  • Returns a pointer to the internal uint64_t storage array.
  • Each word contains 64 logical bits of packed boolean data.
  • Intended for low-level bitwise operations, serialization, or direct memory inspection.
Note
  • This function replaces data() from the generic template, since the bit-packed layout is not contiguous in bool units.
  • Users must manually interpret the bit positions when reading or writing raw words.

◆ raw_word_count()

size_type jh::runtime_arr< bool >::raw_word_count ( ) const
nodiscardnoexcept

Returns the number of 64-bit words used internally to store all bits.

Behavior

  • Computes (size() + 63) / 64, rounding up to the nearest full word.
  • Matches the physical storage capacity, not just logical bit count.
Note
  • Used in conjunction with raw_data() for raw memory operations.
  • Provided as a safe, constexpr-accessible alternative to manual division.

◆ reset_all()

void jh::runtime_arr< bool >::reset_all ( )
noexcept

Resets all bits in the bit-packed array to zero.

Behavior

  • Clears all stored bits by setting every underlying 64-bit word to 0.
  • After the call, all logical elements read as false.
Note
  • This replaces the generic reset_all() implementation for runtime_arr<T>, which performs element-wise assignment.
  • Uses std::memset for efficient zeroing of the bit storage buffer.
  • Equivalent to std::fill(begin(), end(), false) but significantly faster.

◆ set()

void jh::runtime_arr< bool >::set ( std::uint64_t i,
bool val = true )

Sets or clears the bit at given index.

Parameters
iBit index
valBit value to assign (true by default)
Exceptions
std::out_of_rangeif i out of bounds

◆ size()

size_type jh::runtime_arr< bool >::size ( ) const
nodiscardnoexcept

Returns the number of elements in the array.

Returns
Number of elements currently stored.

◆ test()

value_type jh::runtime_arr< bool >::test ( std::uint64_t i) const
nodiscard

Tests if the bit at index is set.

Parameters
iBit index
Returns
true if bit is 1, false if 0
Exceptions
std::out_of_rangeif i out of bounds

◆ unset()

void jh::runtime_arr< bool >::unset ( std::uint64_t i)

Clears the bit at given index.

Parameters
iBit index
Exceptions
std::out_of_rangeif i out of bounds

The documentation for this class was generated from the following file: