Skip to main content

relp_num/integer/big/
mod.rs

1use std::mem;
2
3use smallvec::SmallVec;
4
5/// Unsigned big integer.
6#[derive(Hash, Eq, PartialEq, Clone, Debug)]
7pub struct Ubig<const S: usize>(SmallVec<[usize; S]>);
8/// Non zero unsigned big integer.
9#[derive(Hash, Eq, PartialEq, Clone, Debug)]
10pub struct NonZeroUbig<const S: usize>(SmallVec<[usize; S]>);
11
12pub mod io;
13pub mod ops;
14pub mod properties;
15
16impl<const S: usize> Ubig<S> {
17    pub(crate) unsafe fn is_well_formed(&self) -> bool {
18        match self.0.last() {
19            None => true,
20            Some(&value) => value != 0,
21        }
22    }
23    pub(crate) fn inner(&self) -> &SmallVec<[usize; S]> {
24        &self.0
25    }
26    pub(crate) unsafe fn inner_mut(&mut self) -> &mut SmallVec<[usize; S]> {
27        &mut self.0
28    }
29    pub(crate) fn into_inner(self) -> SmallVec<[usize; S]> {
30        self.0
31    }
32}
33
34impl<const S: usize> NonZeroUbig<S> {
35    pub(crate) unsafe fn is_well_formed(&self) -> bool {
36        match self.0.last() {
37            None => false,
38            Some(&value) => value != 0,
39        }
40    }
41    pub(crate) fn inner(&self) -> &SmallVec<[usize; S]> {
42        &self.0
43    }
44    pub(crate) unsafe fn inner_mut(&mut self) -> &mut SmallVec<[usize; S]> {
45        &mut self.0
46    }
47    pub(crate) fn first(&self) -> &usize {
48        // SAFETY: A `NonZeroUbig` is never empty, so index zero is always in bounds.
49        unsafe {
50            self.0.get_unchecked(0)
51        }
52    }
53    pub(crate) unsafe fn first_mut(&mut self) -> &mut usize {
54        // SAFETY: A `NonZeroUbig` is never empty, so index zero is always in bounds. This is
55        // `unsafe` for what the caller may write through the reference, not for the read: setting
56        // the only word to zero would break that invariant.
57        unsafe { self.0.get_unchecked_mut(0) }
58    }
59    pub(crate) fn into_inner(self) -> SmallVec<[usize; S]> {
60        self.0
61    }
62}
63
64pub const BITS_PER_WORD: u32 = (mem::size_of::<usize>() * 8) as u32;