Skip to main content

crypto_bigint/uint/ref_type/
slice.rs

1use super::UintRef;
2use crate::{Choice, Limb};
3
4impl UintRef {
5    /// Copy the contents from a [`UintRef`].
6    ///
7    /// # Panics
8    /// If `self.nlimbs() != rhs.nlimbs()`
9    #[inline(always)]
10    #[track_caller]
11    pub const fn copy_from(&mut self, rhs: &UintRef) {
12        self.copy_from_slice(&rhs.limbs);
13    }
14
15    /// Conditionally copy the contents from a [`UintRef`].
16    ///
17    /// # Panics
18    /// If `self.nlimbs() != rhs.nlimbs()`
19    #[inline(always)]
20    #[track_caller]
21    pub const fn conditional_copy_from(&mut self, rhs: &UintRef, copy: Choice) {
22        self.conditional_copy_from_slice(&rhs.limbs, copy);
23    }
24
25    /// Copy the contents from a limb slice.
26    ///
27    /// # Panics
28    /// If `self.nlimbs() != limbs.len()`
29    #[inline(always)]
30    #[track_caller]
31    pub const fn copy_from_slice(&mut self, limbs: &[Limb]) {
32        // TODO core::slice::copy_from_slice should eventually be const
33        debug_assert!(self.limbs.len() == limbs.len(), "length mismatch");
34        let mut i = 0;
35        while i < self.limbs.len() {
36            self.limbs[i] = limbs[i];
37            i += 1;
38        }
39    }
40
41    /// Conditionally copy the contents from a limb slice.
42    ///
43    /// # Panics
44    /// If `self.nlimbs() != rhs.nlimbs()`
45    #[inline(always)]
46    #[track_caller]
47    pub const fn conditional_copy_from_slice(&mut self, limbs: &[Limb], copy: Choice) {
48        debug_assert!(self.limbs.len() == limbs.len(), "length mismatch");
49        let mut i = 0;
50        while i < self.limbs.len() {
51            self.limbs[i] = Limb::select(self.limbs[i], limbs[i], copy);
52            i += 1;
53        }
54    }
55
56    /// Fill the limb slice with a repeated limb value.
57    #[inline(always)]
58    pub const fn fill(&mut self, limb: Limb) {
59        let mut i = 0;
60        while i < self.limbs.len() {
61            self.limbs[i] = limb;
62            i += 1;
63        }
64    }
65
66    /// Split the limb slice at a fixed position, producing head and tail slices.
67    #[inline]
68    #[track_caller]
69    #[must_use]
70    pub const fn split_at(&self, mid: usize) -> (&Self, &Self) {
71        let (a, b) = self.limbs.split_at(mid);
72        (UintRef::new(a), UintRef::new(b))
73    }
74
75    /// Split the mutable limb slice at index `mid`, producing head and tail slices.
76    #[inline]
77    #[track_caller]
78    #[must_use]
79    pub const fn split_at_mut(&mut self, mid: usize) -> (&mut Self, &mut Self) {
80        let (a, b) = self.limbs.split_at_mut(mid);
81        (UintRef::new_mut(a), UintRef::new_mut(b))
82    }
83
84    /// Access a limb slice up to a number of elements `len`.
85    #[inline]
86    #[track_caller]
87    #[must_use]
88    pub const fn leading(&self, len: usize) -> &Self {
89        Self::new(self.limbs.split_at(len).0)
90    }
91
92    /// Access a mutable limb slice up to a number of elements `len`.
93    #[inline]
94    #[track_caller]
95    #[must_use]
96    pub const fn leading_mut(&mut self, len: usize) -> &mut Self {
97        Self::new_mut(self.limbs.split_at_mut(len).0)
98    }
99
100    /// Access a limb slice starting from the index `start`.
101    #[inline]
102    #[track_caller]
103    #[must_use]
104    pub const fn trailing(&self, start: usize) -> &Self {
105        Self::new(self.limbs.split_at(start).1)
106    }
107
108    /// Access a mutable limb slice starting from the index `start`.
109    #[inline]
110    #[track_caller]
111    #[must_use]
112    pub const fn trailing_mut(&mut self, start: usize) -> &mut Self {
113        Self::new_mut(self.limbs.split_at_mut(start).1)
114    }
115
116    /// Determine if the slice has zero limbs.
117    #[inline]
118    #[must_use]
119    pub const fn is_empty(&self) -> bool {
120        self.limbs.is_empty()
121    }
122}