Skip to main content

bitsetium/
lib.rs

1//!
2//! `bitsetium` crate contains traits for common bitset operations, and number of implementations.
3//!
4//!
5
6#[cfg(feature = "alloc")]
7extern crate alloc;
8
9mod complement;
10mod difference;
11mod indirect;
12mod intersection;
13mod layered;
14mod ops;
15mod option;
16mod primitive;
17mod union;
18
19pub use self::{
20    complement::Complement, difference::Difference, intersection::Intersection, layered::Layered,
21    ops::*, union::Union,
22};
23
24pub type Bits1 = bool;
25pub type Bits8 = u8;
26pub type Bits16 = u16;
27pub type Bits32 = u32;
28pub type Bits64 = u64;
29pub type Bits128 = u128;
30
31pub type Bits256 = Layered<u32, u8, 32>;
32pub type Bits512 = Layered<u64, u8, 64>;
33pub type Bits1024 = Layered<u64, u16, 64>;
34pub type Bits2048 = Layered<u64, u32, 64>;
35pub type Bits4096 = Layered<u64, u64, 64>;
36pub type Bits8192 = Layered<u64, u128, 64>;
37pub type Bits16384 = Layered<u128, u128, 128>;
38
39#[cfg(feature = "alloc")]
40pub type Bits32768 = Layered<u64, Option<alloc::boxed::Box<Bits512>>, 64>;
41
42#[cfg(feature = "alloc")]
43pub type Bits65536 = Layered<u64, Option<alloc::boxed::Box<Bits1024>>, 64>;
44
45#[cfg(feature = "alloc")]
46pub type Bits131072 = Layered<u64, Option<alloc::boxed::Box<Bits2048>>, 64>;
47
48#[cfg(feature = "alloc")]
49pub type Bits262144 = Layered<u64, Option<alloc::boxed::Box<Bits4096>>, 64>;
50
51#[cfg(feature = "alloc")]
52pub type Bits524288 = Layered<u64, Option<alloc::boxed::Box<Bits8192>>, 64>;
53
54#[cfg(feature = "alloc")]
55pub type Bits1048576 = Layered<u64, Option<alloc::boxed::Box<Bits16384>>, 64>;
56
57#[cfg(feature = "alloc")]
58pub type Bits2097152 = Layered<u64, Option<alloc::boxed::Box<Bits32768>>, 64>;
59
60#[cfg(feature = "alloc")]
61pub type Bits4194304 = Layered<u64, Option<alloc::boxed::Box<Bits65536>>, 64>;
62
63#[cfg(feature = "alloc")]
64pub type Bits8388608 = Layered<u64, Option<alloc::boxed::Box<Bits131072>>, 64>;
65
66#[cfg(feature = "alloc")]
67pub type Bits16777216 = Layered<u64, Option<alloc::boxed::Box<Bits262144>>, 64>;
68
69#[cfg(feature = "alloc")]
70pub type Bits33554432 = Layered<u64, Option<alloc::boxed::Box<Bits524288>>, 64>;
71
72#[cfg(feature = "alloc")]
73pub type Bits67108864 = Layered<u64, Option<alloc::boxed::Box<Bits1048576>>, 64>;
74
75const fn max(a: usize, b: usize) -> usize {
76    if a > b {
77        a
78    } else {
79        b
80    }
81}
82
83const fn min(a: usize, b: usize) -> usize {
84    if a > b {
85        b
86    } else {
87        a
88    }
89}
90
91fn make_array<F, O, const N: usize>(mut f: F) -> [O; N]
92where
93    F: FnMut() -> O,
94{
95    use core::mem::MaybeUninit;
96
97    let mut result = unsafe {
98        // # Safe
99        // All elements are `MaybeUninit` and can be uninit.
100        MaybeUninit::<[MaybeUninit<O>; N]>::uninit().assume_init()
101    };
102
103    for slot in result.iter_mut() {
104        unsafe {
105            // # Safe. Writing to unit but valid and properly aligned memory.
106            // Leaks all previously written elements on panic. Still safe.
107            core::ptr::write(slot, MaybeUninit::new(f()));
108        }
109    }
110
111    unsafe {
112        // # Safe
113        // All elements of the array were initialized.
114        (&result as *const [MaybeUninit<O>; N] as *const [O; N]).read()
115    }
116}
117
118fn map2_arrays<T, U, F, O, const N: usize>(
119    left_array: [T; N],
120    right_array: [U; N],
121    mut f: F,
122) -> [O; N]
123where
124    F: FnMut(T, U) -> O,
125{
126    use core::{array::IntoIter, mem::MaybeUninit};
127
128    let mut result = unsafe {
129        // # Safe
130        // All elements are `MaybeUninit` and can be uninit.
131        MaybeUninit::<[MaybeUninit<O>; N]>::uninit().assume_init()
132    };
133
134    for ((slot, left_elem), right_elem) in result
135        .iter_mut()
136        .zip(IntoIter::new(left_array))
137        .zip(IntoIter::new(right_array))
138    {
139        unsafe {
140            // # Safe. Writing to unit but valid and properly aligned memory.
141            // Leaks all previously written elements on panic. Still safe.
142            core::ptr::write(slot, MaybeUninit::new(f(left_elem, right_elem)));
143        }
144    }
145
146    unsafe {
147        // # Safe
148        // All elements of the array were initialized.
149        (&result as *const [MaybeUninit<O>; N] as *const [O; N]).read()
150    }
151}