Skip to content

Latest commit

 

History

13 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

BitField

A C++23 modular bit array library with three container types: bitarray, bitvector, and bitspan. Built on a shared CRTP base that provides the full bitwise operation set.

Features

  • Three container types — fixed-size (bitarray), dynamic (bitvector), and non-owning view (bitspan)
  • Full bitwise API — set/reset/flip, bitwise operators, shifts, rotations, population count, leading/trailing zero/one counting, bit width, floor/ceil, word/byte/bit swapping
  • Formatting — binary, octal, hexadecimal, and decimal string output
  • CRTP-based — no virtual dispatch; all operations are statically polymorphic
  • C++20 modules — fast compilation, clean interface isolation
  • Customizable word typeuint8_t, uint16_t, uint32_t, uint64_t, or __uint128_t
  • Range-checkedset(), flip(), get_word_at_pos() throw std::out_of_range

Requirements

  • C++23 compiler (tested with Clang 23)
  • CMake 3.28+
  • Ninja build system (recommended)

Quick Start

import BitField;

int main() {
    using Utils::BitField::bitarray;

    bitarray<100> bits;        // 100 bits, stack-allocated
    bits.set(42);              // set bit 42
    bits.set(7, false);        // clear bit 7
    bits.flip(0);              // toggle bit 0
    bits.set();                // set all bits
    bits.reset();              // clear all bits

    auto count = bits.count();       // population count
    auto any   = bits.any();         // any bit set?
    auto none  = bits.none();        // no bits set?
    auto all   = bits.all();         // all bits set?

    auto s = bits.formatted();       // binary: "0b..."
    auto h = bits.formatted(Utils::BitField::Impl::BaseFormat::Hex);  // hex: "0x..."
}

Container Types

bitarray<NBits, Word = uint32_t>

Fixed-size bit array. Storage is a std::array<Word, N> — entirely stack-allocated. Size is known at compile time.

bitarray<64> a;
bitarray<100, uint64_t> b;        // 100 bits using 64-bit words
a.set(0);
a.set(63);
auto c = a | (a << 1);            // bitwise operations return new bitarray

bitvector<NBits, Word = uint32_t>

Dynamic-size bit vector. Storage is a std::vector<Word>. The NBits template parameter is advisory (used for trait selection); actual size is set at runtime.

bitvector<> v;                     // empty
bitvector<> v2{std::vector<uint32_t>{0xFFFFFFFF, 0x00000000}};  // from data
bitvector<> v3{100};               // allocate 100 bits
v.resize(200);                     // grow or shrink
v.set(50);
v.resize(50);                      // shrink

bitspan<Extent = dynamic_extent, Word = uint32_t>

Non-owning view over an existing buffer of words. Storage is a std::span<Word, Extent>. Does not allocate or deallocate.

std::array<uint32_t, 4> buffer{};
bitspan<> view{buffer};               // view over all 128 bits
bitspan<> view2{buffer, 80};          // view over first 80 bits

view.set(7);                           // modifies buffer[0]
view.flip(63);                         // modifies buffer[1]
auto cpy = view;                       // shallow copy (same buffer)

Common API (inherited by all three)

Bit manipulation

Method Description
set(pos, val = true) Set or clear bit at pos
set() Set all bits
reset() Clear all bits
flip(pos) Toggle bit at pos
flip() Toggle all bits

Bitwise operators

Operator Description
a | b Bitwise OR (returns new container)
a & b Bitwise AND
a ^ b Bitwise XOR
~a Bitwise NOT (flip all)
a |= b In-place OR
a &= b In-place AND
a ^= b In-place XOR

Shifts and rotations

Method / Operator Description
a << n Left shift (returns new container)
a <<= n In-place left shift
a >> n Right shift
a >>= n In-place right shift
rotl(n) In-place circular left shift
rotr(n) In-place circular right shift
rotated_left(n) Circular left shift (returns new)
rotated_right(n) Circular right shift (returns new)

Queries

Method Description
size() Number of bits
count() Population count (set bits)
any() Any bit set?
none() No bits set?
all() All bits set?
has_single_bit() Exactly one bit set?
bit_width() Minimum bits needed to represent value
countl_zero() Leading zero bits
countl_one() Leading one bits
countr_zero() Trailing zero bits
countr_one() Trailing one bits

Word-level access

Method Description
get_word_at_pos(pos) Extract a word starting at bit pos
set_word_at_pos(word, pos) Write a word starting at bit pos
data() Direct access to underlying container

Swapping

Method Description
wordswap() Reverse word order
byteswap() Byte-swap each word
bitswap() Bit-reverse each word

Formatting

a.formatted()                          // binary: "0b00010101..."
a.formatted(BaseFormat::Bin)           // explicit binary
a.formatted(BaseFormat::Oct)           // octal
a.formatted(BaseFormat::Hex)           // hexadecimal
a.formatted(BaseFormat::Dec)           // decimal (arbitrary precision)

Format is from MSB to LSB with a prefix (0b, 0o, 0x).

Comparison

a == b             // equality
a != b             // inequality
a <=> b            // three-way (lexicographic)

Building

cmake -B build -G Ninja -DCMAKE_CXX_COMPILER=clang++
cmake --build build

Running tests

build/test_bitarray        # 83 tests
build/test_bitvector       # 52 tests
build/test_bitspan         # 30 tests

Module Structure

src/
  bit_field_impl.cppm      — partition module BitField:Internals
                            CRTP base class bitfield_impl (all operations)
  bit_field.cppm           — primary module BitField
                            bitarray, bitvector, bitspan, traits
tests/
  test_bit_array.cpp       — bitarray tests
  test_bit_vector.cpp      — bitvector tests
  test_bitspan.cpp         — bitspan tests

The primary module exports bitarray and bitvector. The partition contains the CRTP base with all shared implementation.

Implementation Notes

  • All bitwise operations are range-checked — invalid positions throw std::out_of_range
  • Padding bits (bits beyond the logical size in the last word) are kept zero by sanitize()
  • The CRTP base uses private constructors with friend declarations to prevent direct inheritance
  • The formatted() hex output correctly handles digits A-F (unlike naive std::to_string)
  • Rotations (rotl/rotr) handle non-word-aligned sizes correctly

License

MIT

About

Bitfield container with bitwise operations

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages