Skip to content

Commit ab9b853

Browse files
committed
improve docs
1 parent 57de259 commit ab9b853

File tree

3 files changed

+72
-28
lines changed

3 files changed

+72
-28
lines changed

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ num-bigint = { version = "0.4", default-features = false }
1515
serde = { version = "1.0", default-features = false, optional = true }
1616
typesize = { version = "0.1", optional = true, default-features = false }
1717

18+
[lints.rust]
19+
missing_docs = "warn"
20+
1821
[lints.clippy]
1922
nursery = { level = "warn", priority = -1 }
2023
pedantic = { level = "warn", priority = -1 }

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
# smolbitset
44

5-
A library for dynamically sized bitsets with small storage optimization.
5+
A library for dynamically sized bitsets with optimizations for memory usage.
66

7-
All values up to `usize::MAX >> 1` are stored without incurring any heap allocations.\
7+
The first <code>usize::BITS - 1</code> bits are stored without incurring any heap allocations.\
88
Any larger values dynamically allocate an appropriately sized `u32` slice on the heap.\
9-
`SmolBitSet` also has a niche optimization so `Option<SmolBitSet>` and `SmolBitSet` have the same size of 1 `usize`.
9+
Furthermore `SmolBitSet` has a niche optimization so `Option<SmolBitSet>` has the same size of 1 [`usize`].
1010

1111
[ci]: https://github.com/serenity-rs/smolbitset/actions
1212
[ci-badge]: https://img.shields.io/github/actions/workflow/status/serenity-rs/smolbitset/ci.yml?branch=main&style=flat-square

src/lib.rs

Lines changed: 66 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,31 @@
1-
//! A library for dynamically sized bitsets with small storage optimization.
1+
//! A library for dynamically sized bitsets with memory usage optimizations.
2+
//!
3+
//! The first <code>[usize::BITS] - 1</code> bits are stored without incurring any heap allocations.\
4+
//! Any larger values dynamically allocate an appropriately sized [`u32`] slice on the heap.\
5+
//! Furthermore [`SmolBitSet`] has a niche optimization so [`Option<SmolBitSet>`] has the same size of 1 [`usize`].
6+
//!
7+
//! # Example
8+
//!
9+
//! ```
10+
//! use smolbitset::SmolBitSet;
11+
//!
12+
//! let mut sbs = SmolBitSet::new();
13+
//!
14+
//! sbs |= 1u32 << 5;
15+
//! sbs >>= 5u8;
16+
//! assert_eq!(sbs, SmolBitSet::from(1u64));
17+
//!
18+
//! sbs |= !1u64;
19+
//! assert_eq!(sbs, SmolBitSet::from(u64::MAX));
20+
//!
21+
//! sbs <<= 64u16;
22+
//! assert_eq!(sbs, SmolBitSet::from_bits(&(64..128).collect::<Box<[_]>>()))
23+
//! ```
24+
//!
25+
//! # Minimum Supported Rust Version
26+
//!
27+
//! This is currently `1.89`, and is considered a breaking change to increase.
228
//!
3-
//! All values up to `usize::MAX >> 1` are stored without incurring any heap allocations.\
4-
//! Any larger values dynamically allocate an appropriately sized `u32` slice on the heap.\
5-
//! [`SmolBitSet`] also has a niche optimization so [`Option<SmolBitSet>`] and [`SmolBitSet`] have the same size of 1 [`usize`].
629
730
#![doc(html_root_url = "https://docs.rs/smolbitset/*")]
831
#![allow(dead_code)]
@@ -51,20 +74,21 @@ type BitSliceType = u32;
5174
const BST_BITS: usize = BitSliceType::BITS as usize;
5275
const INLINE_SLICE_PARTS: usize = usize::BITS as usize / BST_BITS;
5376

77+
/// A dynamically sized bitset with memory usage optimizations.
78+
///
79+
/// The first <code>[usize::BITS] - 1</code> bits are stored without incurring any heap allocations.
5480
#[repr(transparent)]
5581
pub struct SmolBitSet {
5682
ptr: NonNull<BitSliceType>,
5783
}
5884

5985
impl SmolBitSet {
60-
/// Creates a new empty [`SmolBitSet`].
86+
/// Constructs a new, empty [`SmolBitSet`].
6187
///
6288
/// # Examples
6389
///
6490
/// ```
65-
/// use smolbitset::SmolBitSet;
66-
///
67-
/// # #[allow(unused_mut)]
91+
/// # use smolbitset::SmolBitSet;
6892
/// let mut sbs = SmolBitSet::new();
6993
/// ```
7094
#[must_use]
@@ -75,23 +99,25 @@ impl SmolBitSet {
7599
Self { ptr }
76100
}
77101

78-
/// Creates a new [`SmolBitSet`] from the provided `val` without any heap allocation.
102+
/// Constructs a new [`SmolBitSet`] from the provided `val` without any heap allocations.
79103
///
80104
/// # Panics
81105
///
82-
/// Panics if the most significant bit in `val` is set to 1.
106+
/// Panics if the most significant bit in `val` is 1.
83107
///
84108
/// # Examples
85109
///
86110
/// ```
87-
/// use smolbitset::SmolBitSet;
88-
///
111+
/// # use smolbitset::SmolBitSet;
89112
/// const sbs: SmolBitSet = SmolBitSet::new_small(1234);
90113
/// assert_eq!(sbs, SmolBitSet::from(1234u16));
91114
/// ```
92115
#[must_use]
93116
pub const fn new_small(val: usize) -> Self {
94-
assert!(val.leading_zeros() >= 1, "the highest bit in val must be 0");
117+
assert!(
118+
val.leading_zeros() >= 1,
119+
"the highest bit in val must be 0 for a non allocating SmolBitSet"
120+
);
95121

96122
let mut res = Self::new();
97123
unsafe {
@@ -101,20 +127,33 @@ impl SmolBitSet {
101127
res
102128
}
103129

104-
/// Creates a new [`SmolBitSet`] from the provided array of `bits` without any heap allocation.
130+
/// Constructs a new [`SmolBitSet`] from the provided array of bit indices without any heap allocations.
105131
///
106132
/// # Panics
107133
///
108-
/// Panics if any bit index in `bits` is larger than or equal to `usize::BITS`.
134+
/// Panics if any bit index in `bits` is larger than or equal to [`usize::BITS`].
109135
///
110136
/// # Examples
111137
///
112138
/// ```
113-
/// use smolbitset::SmolBitSet;
114-
///
139+
/// # use smolbitset::SmolBitSet;
115140
/// const sbs: SmolBitSet = SmolBitSet::from_bits_small([0, 4, 1, 6]);
116141
/// assert_eq!(sbs, SmolBitSet::from(0b0101_0011u8));
117142
/// ```
143+
///
144+
/// ```should_panic
145+
/// # use smolbitset::SmolBitSet;
146+
/// // this panics since 63 is outside of the range
147+
/// // a SmolBitSet can hold without incurring a heap allocation
148+
/// let sbs = SmolBitSet::from_bits_small([63]);
149+
/// ```
150+
///
151+
/// ```compile_fail
152+
/// # use smolbitset::SmolBitSet;
153+
/// // this fails to compile since the const evaluation
154+
/// // panics for the same reason as above
155+
/// const sbs: SmolBitSet = SmolBitSet::from_bits_small([63]);
156+
/// ```
118157
#[must_use]
119158
pub const fn from_bits_small<const N: usize>(bits: [usize; N]) -> Self {
120159
let mut res = 0;
@@ -123,8 +162,8 @@ impl SmolBitSet {
123162
while i < N {
124163
let b = bits[i];
125164
assert!(
126-
b < usize::BITS as usize,
127-
"bit index out of range for small bitset"
165+
b < usize::BITS as usize - 1,
166+
"bit index out of range for a non allocating SmolBitSet"
128167
);
129168

130169
res |= 1 << b;
@@ -134,17 +173,18 @@ impl SmolBitSet {
134173
Self::new_small(res)
135174
}
136175

137-
/// Creates a new [`SmolBitSet`] from the provided slice of `bits`.
176+
/// Creates a new [`SmolBitSet`] from the provided slice of bit indices.
138177
///
139178
/// # Examples
140179
///
141180
/// ```
142-
/// use smolbitset::SmolBitSet;
143-
///
144-
/// let sbs = SmolBitSet::from_bits(&[0, 4, 3, 6]);
181+
/// # use smolbitset::SmolBitSet;
182+
/// // bit indices can be in any order
183+
/// let sbs = SmolBitSet::from_bits(&[0, 6, 4, 3]);
145184
/// assert_eq!(sbs, SmolBitSet::from(0b0101_1001u8));
146-
/// # let sbs = SmolBitSet::from_bits(&[63]);
147-
/// # assert_eq!(sbs, SmolBitSet::from(1u64 << 63));
185+
///
186+
/// let sbs = SmolBitSet::from_bits(&[63]);
187+
/// assert_eq!(sbs, SmolBitSet::from(1u64 << 63));
148188
/// ```
149189
#[must_use]
150190
pub fn from_bits(bits: &[usize]) -> Self {
@@ -336,6 +376,7 @@ impl SmolBitSet {
336376

337377
/// Returns the index of the most significant bit set to 1.
338378
///
379+
/// # Warning
339380
/// The least significant bit is at index 1!
340381
#[inline]
341382
fn highest_set_bit(&self) -> usize {

0 commit comments

Comments
 (0)