Skip to content

Commit f423867

Browse files
authored
Add array/slice Limb => Word cast helpers (#1103)
Adds the following functions which can cast from arrays or slices of `Limb` to `Word`: - `Limb::array_as_words` - `Limb::array_as_mut_words` - `Limb::slice_as_words` - `Limb::slice_as_mut_words`
1 parent 75e45d5 commit f423867

3 files changed

Lines changed: 50 additions & 20 deletions

File tree

src/limb.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,50 @@ impl Limb {
9494
pub const fn lsb_to_choice(self) -> Choice {
9595
word::choice_from_lsb(self.0)
9696
}
97+
98+
/// Convert a shared reference to an array of [`Limb`]s into a shared reference to their inner
99+
/// [`Word`]s for each limb.
100+
#[inline]
101+
pub const fn array_as_words<const N: usize>(array: &[Self; N]) -> &[Word; N] {
102+
// SAFETY: `Limb` is a `repr(transparent)` newtype for `Word`
103+
#[allow(unsafe_code)]
104+
unsafe {
105+
&*array.as_ptr().cast()
106+
}
107+
}
108+
109+
/// Convert a mutable reference to an array of [`Limb`]s into a mutable reference to their inner
110+
/// [`Word`]s for each limb.
111+
#[inline]
112+
pub const fn array_as_mut_words<const N: usize>(array: &mut [Self; N]) -> &mut [Word; N] {
113+
// SAFETY: `Limb` is a `repr(transparent)` newtype for `Word`
114+
#[allow(unsafe_code)]
115+
unsafe {
116+
&mut *array.as_mut_ptr().cast()
117+
}
118+
}
119+
120+
/// Convert a shared reference to an array of [`Limb`]s into a shared reference to their inner
121+
/// [`Word`]s for each limb.
122+
#[inline]
123+
pub const fn slice_as_words(slice: &[Self]) -> &[Word] {
124+
// SAFETY: `Limb` is a `repr(transparent)` newtype for `Word`
125+
#[allow(trivial_casts, unsafe_code)]
126+
unsafe {
127+
&*((slice as *const [Limb]) as *const [Word])
128+
}
129+
}
130+
131+
/// Convert a mutable reference to an array of [`Limb`]s into a mutable reference to their inner
132+
/// [`Word`]s for each limb.
133+
#[inline]
134+
pub const fn slice_as_mut_words(slice: &mut [Self]) -> &mut [Word] {
135+
// SAFETY: `Limb` is a `repr(transparent)` newtype for `Word`
136+
#[allow(trivial_casts, unsafe_code)]
137+
unsafe {
138+
&mut *((slice as *mut [Limb]) as *mut [Word])
139+
}
140+
}
97141
}
98142

99143
impl Bounded for Limb {

src/uint.rs

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -152,20 +152,12 @@ impl<const LIMBS: usize> Uint<LIMBS> {
152152

153153
/// Borrow the inner limbs as an array of [`Word`]s.
154154
pub const fn as_words(&self) -> &[Word; LIMBS] {
155-
// SAFETY: `Limb` is a `repr(transparent)` newtype for `Word`
156-
#[allow(unsafe_code)]
157-
unsafe {
158-
&*self.limbs.as_ptr().cast()
159-
}
155+
Limb::array_as_words(&self.limbs)
160156
}
161157

162158
/// Borrow the inner limbs as a mutable array of [`Word`]s.
163159
pub const fn as_mut_words(&mut self) -> &mut [Word; LIMBS] {
164-
// SAFETY: `Limb` is a `repr(transparent)` newtype for `Word`
165-
#[allow(unsafe_code)]
166-
unsafe {
167-
&mut *self.limbs.as_mut_ptr().cast()
168-
}
160+
Limb::array_as_mut_words(&mut self.limbs)
169161
}
170162

171163
/// Borrow the inner limbs as a mutable slice of [`Word`]s.
@@ -233,6 +225,8 @@ impl<const LIMBS: usize> Uint<LIMBS> {
233225
///
234226
/// Note: this is a casting operation. See [`Self::try_into_int`] for the checked equivalent.
235227
pub const fn as_int(&self) -> &Int<LIMBS> {
228+
// SAFETY: `Int` is a `repr(transparent)` newtype for `Uint`, and this operation is intended
229+
// to be a reinterpreting cast between the two types.
236230
#[allow(trivial_casts, unsafe_code)]
237231
unsafe {
238232
&*(self as *const Uint<LIMBS> as *const Int<LIMBS>)

src/uint/ref_type.rs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -71,22 +71,14 @@ impl UintRef {
7171
#[cfg(feature = "alloc")]
7272
#[inline]
7373
pub const fn as_words(&self) -> &[Word] {
74-
// SAFETY: `Limb` is a `repr(transparent)` newtype for `Word`
75-
#[allow(trivial_casts, unsafe_code)]
76-
unsafe {
77-
&*((&self.0 as *const [Limb]) as *const [Word])
78-
}
74+
Limb::slice_as_words(&self.0)
7975
}
8076

8177
/// Borrow the inner limbs as a mutable slice of [`Word`]s.
8278
#[cfg(feature = "alloc")]
8379
#[inline]
8480
pub const fn as_mut_words(&mut self) -> &mut [Word] {
85-
// SAFETY: `Limb` is a `repr(transparent)` newtype for `Word`
86-
#[allow(trivial_casts, unsafe_code)]
87-
unsafe {
88-
&mut *((&mut self.0 as *mut [Limb]) as *mut [Word])
89-
}
81+
Limb::slice_as_mut_words(&mut self.0)
9082
}
9183

9284
/// Get an iterator over the inner limbs.

0 commit comments

Comments
 (0)