Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "bit-string"
version = "0.4.2"
version = "0.4.3"
edition = "2024"
description = "A compact owned bit string type with editing, matching, and bitwise operations."
readme = "README.md"
Expand Down
31 changes: 28 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,28 @@
[![CodSpeed](https://img.shields.io/endpoint?url=https://codspeed.io/badge.json)](https://codspeed.io/gh/jcfangc/bit-string)
[![Coverage](https://codecov.io/gh/jcfangc/bit-string/branch/main/graph/badge.svg)](https://codecov.io/gh/jcfangc/bit-string)

A `no_std` Rust crate providing a compact owned bit string type with construction, editing, matching, and bitwise operations.
A `no_std` Rust crate providing a compact owned bit string type and a zero-copy view, with construction, editing, matching, comparison, hashing, and bitwise operations.

The core type is `BitString`. Bits are packed into `Box<[u64]>` with unused high bits in the last word always zero (masked after every mutation).
The two core types mirror the `String`/`&str` relationship:

| Type | Role | Size | `Copy` |
|------|------|------|--------|
| `BitString` | Owned bit string, backed by `Box<[u64]>` | 4×usize | No |
| `BitStr<'bs>` | Zero-copy borrowed view of a `BitString` or subrange | 3×usize (24 bytes) | **Yes** |

Bits are packed little-endian into `u64` words. Unused high bits in the last word are always zero — enforced after every mutation on `BitString` and never observable through `BitStr`.

## Features

- **Construction**: `new`, `zeros`, `repeat`, `from_bool_iter`, `from_words`, `try_from(&str)`
- **Zero-copy view**: `BitStr<'bs>` — 24-byte `Copy` type returned by `as_bit_str()`, `slice()`, `slice_from()`, `slice_until()`
- **Conversion**: `to_bit_string()` — copies a `BitStr` view into an owned `BitString`
- **Bitwise ops**: `and`, `or`, `xor`, `not`, `shl`, `shr` (each with `_assign` and `_into` variants)
- **Bit counting**: `count_ones`, `count_zeros`
- **Editing**: `push`, `pop`, `insert`, `remove`, `set`, `extend`, `truncate`, `slice`, `split_off`, `replace_interval`, `retain`, `push_bit_string`, `insert_bit_string`
- **Matching**: `starts_with`, `ends_with`, `contains`, `find`, `rfind`, `strip_prefix`, `strip_suffix`
- **Access**: `get`, `len`, `is_empty`, `as_words`, `get_chunk`, `to_string`, `iter`
- **Comparison & hashing**: `PartialEq`, `Eq`, `PartialOrd`, `Ord`, `Hash` for both `BitStr` and `BitString` — lexicographic comparison with SIMD acceleration
- **Access**: `get`, `first`, `last`, `get_chunk`, `len`/`bit_len`, `is_empty`, `words`, `iter`

### SIMD backends

Expand All @@ -40,10 +50,25 @@ use bit_string::BitString;
let a = BitString::try_from("1010").unwrap();
let b = BitString::try_from("1100").unwrap();

// Bitwise operations
assert_eq!(a.and(&b).unwrap().to_string(), "1000");
assert_eq!(a.or(&b).unwrap().to_string(), "1110");
assert_eq!((!a).to_string(), "0101");
assert_eq!(a.count_ones(), 2);

// Zero-copy views via BitStr
let view = a.as_bit_str(); // &BitString → BitStr
let sub = view.slice_from(1); // "010"
assert!(sub.starts_with(&BitString::try_from("01").unwrap().as_bit_str()));
assert_eq!(sub.count_ones(), 1);

// Comparison
use core::cmp::Ordering;
assert_eq!(a.cmp(&b), Ordering::Less); // "1010" < "1100"

// Convert back to owned
let owned = sub.to_bit_string();
assert_eq!(owned.to_string(), "010");
```

## Benchmarks
Expand Down
Loading