1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
//! # bitmac
//! This library provides implementation of bitmap with custom bit access,
//! a custom inner container and a variable or static container size.
//!
//! ## Features
//!
//! | Feature    | Description                                                                                                                            |
//! |------------|----------------------------------------------------------------------------------------------------------------------------------------|
//! | `bytes`    | to implement [`ContainerRead`] trait for [`Bytes`] and [`ContainerRead`], [`ContainerWrite`] and [`Resizable`] traits for [`BytesMut`] |
//! | `smallvec` | to implement [`ContainerRead`], [`ContainerWrite`] and [`Resizable`] traits for [`SmallVec`]                                           |
//!
//! ## BitAccess
//!
//! [`BitAccess`] is a trait that provides functions for accessing single bit in [`Number`].
//!
//! - [`LSB`]
//! - [`MSB`]
//!
//! ## ContainerRead & ContainerWrite
//!
//! [`ContainerRead`] and [`ContainerWrite`] are traits provides functions for accessing single slot ([`Number`]) in container.
//!
//! - `ContainerRead` for read-only access
//! - `ContainerWrite` for mutable access
//!
//! The traits are implemented for most standard types:
//! - `Vec<T>`
//! - `[T; N]`
//! - `&[T]`
//! - `&mut [T]`
//! - `T`
//! - `Bytes`
//! - `BytesMut`
//! - `SmallVec`
//!
//! You can implement them for your custom containers, the only one constraint is that containers should
//! consist of `Number`'s.
//!
//! ## StaticBitmap
//!
//! [`StaticBitmap`] is a bitmap that cannot be resized.
//!
//! Any structure that implements the [`ContainerRead`] (for read-only access) and [`ContainerWrite`]
//! (for mutable access) traits can be a container of bitmap (e.g. `[T; N]`, `&[T]`, `Vec<T>`, etc.).
//!
//! Usage example:
//! ```
//! # fn main() {
//! use bitmac::{StaticBitmap, LSB};
//!
//! // You can directly check every single bit
//! let bitmap = StaticBitmap::<_, LSB>::new([0b0000_0001u8, 0b0000_1000]);
//! assert!(bitmap.get(0));
//! assert!(bitmap.get(11));
//! assert!(!bitmap.get(13));
//! // Out of bounds bits always return false
//! assert!(!bitmap.get(128));
//!
//! // You can iterate over bits
//! let bitmap = StaticBitmap::<_, LSB>::new([0b0000_1001u8, 0b0000_1000]);
//! let mut iter = bitmap.iter().by_bits().enumerate();
//! assert_eq!(iter.next(), Some((0, true)));
//! assert_eq!(iter.next(), Some((1, false)));
//! assert_eq!(iter.next(), Some((2, false)));
//! assert_eq!(iter.next(), Some((3, true)));
//! assert_eq!(iter.next(), Some((4, false)));
//!
//! // You can check multiple bits at the same time through the intersection
//! use bitmac::Intersection;
//! let bitmap = StaticBitmap::<_, LSB>::new([0b0000_1001u8, 0b0000_1000]);
//! // .. by creating specific new container for result
//! let test = [0b0000_1001u8, 0b0000_0000];
//! assert_eq!(bitmap.intersection::<[u8; 2]>(&test), test);
//! // .. by using preallocated container for result
//! let test = [0b0000_1001u8, 0b0000_0000];
//! let mut result = [0u8; 2];
//! bitmap.intersection_in(&test, &mut result);
//! assert_eq!(result, test);
//! // .. by comparing length of difference that is equivalent to count of ones (bits) in result
//! let test = [0b0000_1001u8, 0b0000_0000];
//! assert_eq!(bitmap.intersection_len(&test), test.iter().fold(0, |acc, &v| acc + v.count_ones() as usize));
//!
//! // You can directly change every single bit
//! let mut bitmap = StaticBitmap::<_, LSB>::new([0b0000_1001u8, 0b0001_1000]);
//! assert!(bitmap.get(0));
//! assert!(bitmap.get(3));
//! assert!(bitmap.get(11));
//! assert!(bitmap.get(12));
//! assert!(!bitmap.get(13));
//! assert!(!bitmap.get(128));
//! bitmap.set(12, false);
//! assert!(!bitmap.get(12));
//! bitmap.set(13, true);
//! assert!(bitmap.get(13));
//! // Out of bounds bits return error
//! assert!(bitmap.try_set(128, true).is_err());
//! assert!(!bitmap.get(128));
//! # }
//! ```
//!
//! ## VarBitmap
//!
//! [`VarBitmap`] is a bitmap that can be resized by custom resizing strategy.
//!
//! Any structure that implements the [`ContainerRead`] (for read-only access) and
//! [`ContainerWrite`] + [`Resizable`] (for mutable access) traits can be a container of bitmap (e.g. `Vec<T>`).
//!
//! It has the same interface as `StaticBitmap` except that mutable access requires resizable container.
//! Container tries to grow if the changing bit is out of bounds.
//!
//! Usage example:
//! ```
//! # fn main() {
//! use bitmac::{VarBitmap, LSB, MinimumRequiredStrategy};
//!
//! // You can directly check every single bit
//! let bitmap = VarBitmap::<_, LSB, MinimumRequiredStrategy>::from_container(vec![0b0000_0001u8]);
//! assert!(bitmap.get(0));
//! assert!(!bitmap.get(11));
//! assert!(!bitmap.get(13));
//!
//! // You can iterate over bits
//! let bitmap = VarBitmap::<_, LSB, MinimumRequiredStrategy>::from_container(vec![0b0000_1001u8, 0b0000_1000]);
//! let mut iter = bitmap.iter().by_bits().enumerate();
//! assert_eq!(iter.next(), Some((0, true)));
//! assert_eq!(iter.next(), Some((1, false)));
//! assert_eq!(iter.next(), Some((2, false)));
//! assert_eq!(iter.next(), Some((3, true)));
//! assert_eq!(iter.next(), Some((4, false)));
//!
//! // You can check multiple bits at the same time through the intersection
//! use bitmac::Intersection;
//! let bitmap = VarBitmap::<_, LSB, MinimumRequiredStrategy>::from_container(vec![0b0000_1001u8, 0b0000_1000]);
//! // .. by creating specific new container for result
//! let test = [0b0000_1001u8, 0b0000_0000];
//! assert_eq!(bitmap.intersection::<[u8; 2]>(&test), test);
//! // .. by using preallocated container for result
//! let test = [0b0000_1001u8, 0b0000_0000];
//! let mut result = [0u8; 2];
//! bitmap.intersection_in(&test, &mut result);
//! assert_eq!(result, test);
//! // .. by comparing length of difference that is equivalent to count of ones (bits) in result
//! let test = [0b0000_1001u8, 0b0000_0000];
//! assert_eq!(bitmap.intersection_len(&test), test.iter().fold(0, |acc, &v| acc + v.count_ones() as usize));
//!
//! // You can directly change every bit
//! let mut bitmap = VarBitmap::<_, LSB, MinimumRequiredStrategy>::from_container(vec![0b0000_1001u8, 0b0001_1000]);
//! assert!(bitmap.get(0));
//! assert!(bitmap.get(3));
//! assert!(bitmap.get(11));
//! assert!(bitmap.get(12));
//! assert!(!bitmap.get(13));
//! assert!(!bitmap.get(128));
//! bitmap.set(12, false);
//! assert!(!bitmap.get(12));
//! bitmap.set(13, true);
//! assert!(bitmap.get(13));
//! // If you change the bit exceeding container's length and new bit state is `1` (`true`)
//! // then the container will automatically grow
//! bitmap.set(127, true);
//! assert!(bitmap.get(127));
//! assert_eq!(bitmap.as_ref().len(), 16);
//! # }
//! ```
//!
//! ### GrowStrategy
//!
//! [`GrowStrategy`] is a trait that controls how container will grow.
//! There are already several useful implemented strategies, but you can create your own.
//!
//! - [`MinimumRequiredStrategy`]
//! - [`FixedStrategy`]
//! - [`LimitStrategy`]
//! - [`ForceGrowStrategy`]
//!
//! ### TryWithSlots
//!
//! [`TryWithSlots`] is a trait with which you can create a container with a known size.
//!
//! The trait is already implemented for every type that implements `Default` + `Resizable<Slot: Number>`.
//!
//! [`GrowStrategy`]: crate::grow_strategy::GrowStrategy
//! [`MinimumRequiredStrategy`]: crate::grow_strategy::MinimumRequiredStrategy
//! [`FixedStrategy`]: crate::grow_strategy::FixedStrategy
//! [`LimitStrategy`]: crate::grow_strategy::LimitStrategy
//! [`ForceGrowStrategy`]: crate::grow_strategy::ForceGrowStrategy
//! [`BitAccess`]: crate::bit_access::BitAccess
//! [`LSB`]: crate::bit_access::LSB
//! [`MSB`]: crate::bit_access::MSB
//! [`ContainerRead`]: crate::container::ContainerRead
//! [`ContainerWrite`]: crate::container::ContainerWrite
//! [`Resizable`]: crate::resizable::Resizable
//! [`Number`]: crate::number::Number
//! [`TryWithSlots`]: crate::with_slots::TryWithSlots
//! [`VarBitmap`]: crate::var_bitmap::VarBitmap
//! [`StaticBitmap`]: crate::static_bitmap::StaticBitmap
//! [`Bytes`]: https://docs.rs/bytes/latest/bytes/
//! [`BytesMut`]: https://docs.rs/bytes/latest/bytes/
//! [`SmallVec`]: https://docs.rs/smallvec/latest/smallvec/

pub mod bit_access;
pub mod container;
pub mod error;
pub mod grow_strategy;
pub mod intersection;
pub mod iter;
pub mod number;
pub mod resizable;
pub mod static_bitmap;
pub mod union;
pub mod var_bitmap;
pub mod with_slots;

pub use bit_access::{BitAccess, LSB, MSB};
pub use error::{
    IntersectionError, OutOfBoundsError, ResizeError, SmallContainerSizeError, UnionError,
    WithSlotsError,
};
pub use grow_strategy::{FixedStrategy, LimitStrategy, MinimumRequiredStrategy};
pub use intersection::Intersection;
pub use static_bitmap::StaticBitmap;
pub use union::Union;
pub use var_bitmap::VarBitmap;