Skip to content

Commit 1595964

Browse files
authored
Uint: change split_mixed to accept self; make pub (#556)
The `split_mixed` method provides a `const fn`-friendly way to split numbers. This refactors it to be a method that accepts `self` as an argument so it can be called as `uint.split_mixed()` and also exposes it as `pub`, allowing downstream users to use it in `const fn` contexts. A newly added `SplitMixed` bound typechecks the sizes of the outputs to ensure that they're a valid combination, which is the best we can do absent something like `generic_const_exprs`.
1 parent 313505f commit 1595964

3 files changed

Lines changed: 31 additions & 25 deletions

File tree

src/uint/from.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! `From`-like conversions for [`Uint`].
22
3-
use crate::{ConcatMixed, Limb, Uint, WideWord, Word, U128, U64};
3+
use crate::{ConcatMixed, Limb, SplitMixed, Uint, WideWord, Word, U128, U64};
44

55
impl<const LIMBS: usize> Uint<LIMBS> {
66
/// Create a [`Uint`] from a `u8` (const-friendly)
@@ -214,9 +214,12 @@ where
214214
}
215215
}
216216

217-
impl<const L: usize, const H: usize, const LIMBS: usize> From<Uint<LIMBS>> for (Uint<L>, Uint<H>) {
217+
impl<const L: usize, const H: usize, const LIMBS: usize> From<Uint<LIMBS>> for (Uint<L>, Uint<H>)
218+
where
219+
Uint<LIMBS>: SplitMixed<Uint<L>, Uint<H>>,
220+
{
218221
fn from(num: Uint<LIMBS>) -> (Uint<L>, Uint<H>) {
219-
crate::uint::split::split_mixed(&num)
222+
num.split_mixed()
220223
}
221224
}
222225

src/uint/macros.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ macro_rules! impl_uint_concat_split_mixed {
9090
impl $crate::traits::SplitMixed<Uint<{ U64::LIMBS * $size }>, Uint<{ <$name>::LIMBS - U64::LIMBS * $size }>> for $name
9191
{
9292
fn split_mixed(&self) -> (Uint<{ U64::LIMBS * $size }>, Uint<{ <$name>::LIMBS - U64::LIMBS * $size }>) {
93-
$crate::uint::split::split_mixed(self)
93+
self.split_mixed()
9494
}
9595
}
9696
};
@@ -128,7 +128,7 @@ macro_rules! impl_uint_concat_split_even {
128128
impl $crate::traits::SplitMixed<Uint<{ <$name>::LIMBS / 2 }>, Uint<{ <$name>::LIMBS / 2 }>> for $name
129129
{
130130
fn split_mixed(&self) -> (Uint<{ <$name>::LIMBS / 2 }>, Uint<{ <$name>::LIMBS / 2 }>) {
131-
$crate::uint::split::split_mixed(self)
131+
self.split_mixed()
132132
}
133133
}
134134

@@ -140,7 +140,7 @@ macro_rules! impl_uint_concat_split_even {
140140
impl $name {
141141
/// Split this number in half, returning its low and high components respectively.
142142
pub const fn split(&self) -> (Uint<{ <$name>::LIMBS / 2 }>, Uint<{ <$name>::LIMBS / 2 }>) {
143-
$crate::uint::split::split_mixed(self)
143+
self.split_mixed()
144144
}
145145
}
146146
};

src/uint/split.rs

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,29 @@
1-
use crate::{Limb, Uint};
1+
use crate::{Limb, SplitMixed, Uint};
22

3-
/// Split this number in half, returning its low and high components respectively.
4-
#[inline]
5-
pub(crate) const fn split_mixed<const L: usize, const H: usize, const O: usize>(
6-
n: &Uint<O>,
7-
) -> (Uint<L>, Uint<H>) {
8-
let top = L + H;
9-
let top = if top < O { top } else { O };
10-
let mut lo = [Limb::ZERO; L];
11-
let mut hi = [Limb::ZERO; H];
12-
let mut i = 0;
3+
impl<const I: usize> Uint<I> {
4+
/// Split this number into low and high components respectively.
5+
#[inline]
6+
pub const fn split_mixed<const L: usize, const H: usize>(&self) -> (Uint<L>, Uint<H>)
7+
where
8+
Self: SplitMixed<Uint<L>, Uint<H>>,
9+
{
10+
let top = L + H;
11+
let top = if top < I { top } else { I };
12+
let mut lo = [Limb::ZERO; L];
13+
let mut hi = [Limb::ZERO; H];
14+
let mut i = 0;
1315

14-
while i < top {
15-
if i < L {
16-
lo[i] = n.limbs[i];
17-
} else {
18-
hi[i - L] = n.limbs[i];
16+
while i < top {
17+
if i < L {
18+
lo[i] = self.limbs[i];
19+
} else {
20+
hi[i - L] = self.limbs[i];
21+
}
22+
i += 1;
1923
}
20-
i += 1;
21-
}
2224

23-
(Uint { limbs: lo }, Uint { limbs: hi })
25+
(Uint { limbs: lo }, Uint { limbs: hi })
26+
}
2427
}
2528

2629
#[cfg(test)]

0 commit comments

Comments
 (0)