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
//!
//! `bitsetium` crate contains traits for common bitset operations, and number of implementations.
//!
//!

#[cfg(feature = "alloc")]
extern crate alloc;

mod complement;
mod difference;
mod indirect;
mod intersection;
mod layered;
mod ops;
mod option;
mod primitive;
mod union;

pub use self::{
    complement::Complement, difference::Difference, intersection::Intersection, layered::Layered,
    ops::*, union::Union,
};

pub type Bits1 = bool;
pub type Bits8 = u8;
pub type Bits16 = u16;
pub type Bits32 = u32;
pub type Bits64 = u64;
pub type Bits128 = u128;

pub type Bits256 = Layered<u32, u8, 32>;
pub type Bits512 = Layered<u64, u8, 64>;
pub type Bits1024 = Layered<u64, u16, 64>;
pub type Bits2048 = Layered<u64, u32, 64>;
pub type Bits4096 = Layered<u64, u64, 64>;
pub type Bits8192 = Layered<u64, u128, 64>;
pub type Bits16384 = Layered<u128, u128, 128>;

#[cfg(feature = "alloc")]
pub type Bits32768 = Layered<u64, Option<alloc::boxed::Box<Bits512>>, 64>;

#[cfg(feature = "alloc")]
pub type Bits65536 = Layered<u64, Option<alloc::boxed::Box<Bits1024>>, 64>;

#[cfg(feature = "alloc")]
pub type Bits131072 = Layered<u64, Option<alloc::boxed::Box<Bits2048>>, 64>;

#[cfg(feature = "alloc")]
pub type Bits262144 = Layered<u64, Option<alloc::boxed::Box<Bits4096>>, 64>;

#[cfg(feature = "alloc")]
pub type Bits524288 = Layered<u64, Option<alloc::boxed::Box<Bits8192>>, 64>;

#[cfg(feature = "alloc")]
pub type Bits1048576 = Layered<u64, Option<alloc::boxed::Box<Bits16384>>, 64>;

#[cfg(feature = "alloc")]
pub type Bits2097152 = Layered<u64, Option<alloc::boxed::Box<Bits32768>>, 64>;

#[cfg(feature = "alloc")]
pub type Bits4194304 = Layered<u64, Option<alloc::boxed::Box<Bits65536>>, 64>;

#[cfg(feature = "alloc")]
pub type Bits8388608 = Layered<u64, Option<alloc::boxed::Box<Bits131072>>, 64>;

#[cfg(feature = "alloc")]
pub type Bits16777216 = Layered<u64, Option<alloc::boxed::Box<Bits262144>>, 64>;

#[cfg(feature = "alloc")]
pub type Bits33554432 = Layered<u64, Option<alloc::boxed::Box<Bits524288>>, 64>;

#[cfg(feature = "alloc")]
pub type Bits67108864 = Layered<u64, Option<alloc::boxed::Box<Bits1048576>>, 64>;

const fn max(a: usize, b: usize) -> usize {
    if a > b {
        a
    } else {
        b
    }
}

const fn min(a: usize, b: usize) -> usize {
    if a > b {
        b
    } else {
        a
    }
}

fn make_array<F, O, const N: usize>(mut f: F) -> [O; N]
where
    F: FnMut() -> O,
{
    use core::mem::MaybeUninit;

    let mut result = unsafe {
        // # Safe
        // All elements are `MaybeUninit` and can be uninit.
        MaybeUninit::<[MaybeUninit<O>; N]>::uninit().assume_init()
    };

    for slot in result.iter_mut() {
        unsafe {
            // # Safe. Writing to unit but valid and properly aligned memory.
            // Leaks all previously written elements on panic. Still safe.
            core::ptr::write(slot, MaybeUninit::new(f()));
        }
    }

    unsafe {
        // # Safe
        // All elements of the array were initialized.
        (&result as *const [MaybeUninit<O>; N] as *const [O; N]).read()
    }
}

fn map2_arrays<T, U, F, O, const N: usize>(
    left_array: [T; N],
    right_array: [U; N],
    mut f: F,
) -> [O; N]
where
    F: FnMut(T, U) -> O,
{
    use core::{array::IntoIter, mem::MaybeUninit};

    let mut result = unsafe {
        // # Safe
        // All elements are `MaybeUninit` and can be uninit.
        MaybeUninit::<[MaybeUninit<O>; N]>::uninit().assume_init()
    };

    for ((slot, left_elem), right_elem) in result
        .iter_mut()
        .zip(IntoIter::new(left_array))
        .zip(IntoIter::new(right_array))
    {
        unsafe {
            // # Safe. Writing to unit but valid and properly aligned memory.
            // Leaks all previously written elements on panic. Still safe.
            core::ptr::write(slot, MaybeUninit::new(f(left_elem, right_elem)));
        }
    }

    unsafe {
        // # Safe
        // All elements of the array were initialized.
        (&result as *const [MaybeUninit<O>; N] as *const [O; N]).read()
    }
}