From 942c82dd61e686a9ffba80e28f55601c5dab1ad1 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Fri, 11 Apr 2025 08:58:46 +0100 Subject: [PATCH] I think that's refs, split and join? --- src/finitenimber.rs | 48 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/src/finitenimber.rs b/src/finitenimber.rs index 51cfc68..8577a23 100644 --- a/src/finitenimber.rs +++ b/src/finitenimber.rs @@ -1,4 +1,4 @@ -use std::ops::Add; +use core::ops::Add; type Word = u64; // element type of the vectors we use const WORDLEVELS: usize = 6; // 2^{2^6} = 64 = size of Word @@ -73,7 +73,7 @@ impl<'a> FiniteNimberRef<'a> { 'b: 'c, { match self { - OneWord(v) => std::slice::from_ref(v), + OneWord(v) => core::slice::from_ref(v), Slice(s) => s, } } @@ -114,4 +114,48 @@ impl<'a> FiniteNimberRef<'a> { }, } } + + fn join(self, hi: FiniteNimberRef<'_>, level: usize) -> FiniteNimber { + match level.checked_sub(WORDLEVELS) { + None => { + // If level < WORDLEVELS then we can cast to Word any old way + let bits = 1 << (level as Word); + let mask = bits - 1; + let vlo = self.low_word(); + let vhi = hi.low_word(); + ((vlo & mask) | ((vhi & mask) << bits)).into() + } + Some(wordlevel) => { + match wordlevel + .try_into() + .ok() + .and_then(|w| 1usize.checked_shl(w)) + { + Some(words) => { + let slo = self.as_slice(); + let shi = hi.as_slice(); + let padding = words.saturating_sub(slo.len()); + FiniteNimber( + slo.iter() + .cloned() + .take(words) + .chain(core::iter::repeat(0).take(padding)) + .chain(shi.iter().cloned().take(words)) + .collect(), + ) + } + None => FiniteNimber(self.as_slice().into()), + } + } + } + } +} + +impl<'a> From<&'a FiniteNimber> for FiniteNimberRef<'a> { + fn from(n: &'a FiniteNimber) -> Self { + match n.0.len() { + 0 => Self::zero(), + _ => Slice(&n.0), + } + } } -- 2.30.2