1cbd624adSopenharmony_ci//! Simple heap-allocated vector. 2cbd624adSopenharmony_ci 3cbd624adSopenharmony_ci#![cfg(feature = "alloc")] 4cbd624adSopenharmony_ci#![doc(hidden)] 5cbd624adSopenharmony_ci 6cbd624adSopenharmony_ciuse crate::bigint; 7cbd624adSopenharmony_ci#[cfg(not(feature = "std"))] 8cbd624adSopenharmony_ciuse alloc::vec::Vec; 9cbd624adSopenharmony_ciuse core::{cmp, ops}; 10cbd624adSopenharmony_ci#[cfg(feature = "std")] 11cbd624adSopenharmony_ciuse std::vec::Vec; 12cbd624adSopenharmony_ci 13cbd624adSopenharmony_ci/// Simple heap vector implementation. 14cbd624adSopenharmony_ci#[derive(Clone)] 15cbd624adSopenharmony_cipub struct HeapVec { 16cbd624adSopenharmony_ci /// The heap-allocated buffer for the elements. 17cbd624adSopenharmony_ci data: Vec<bigint::Limb>, 18cbd624adSopenharmony_ci} 19cbd624adSopenharmony_ci 20cbd624adSopenharmony_ci#[allow(clippy::new_without_default)] 21cbd624adSopenharmony_ciimpl HeapVec { 22cbd624adSopenharmony_ci /// Construct an empty vector. 23cbd624adSopenharmony_ci #[inline] 24cbd624adSopenharmony_ci pub fn new() -> Self { 25cbd624adSopenharmony_ci Self { 26cbd624adSopenharmony_ci data: Vec::with_capacity(bigint::BIGINT_LIMBS), 27cbd624adSopenharmony_ci } 28cbd624adSopenharmony_ci } 29cbd624adSopenharmony_ci 30cbd624adSopenharmony_ci /// Construct a vector from an existing slice. 31cbd624adSopenharmony_ci #[inline] 32cbd624adSopenharmony_ci pub fn try_from(x: &[bigint::Limb]) -> Option<Self> { 33cbd624adSopenharmony_ci let mut vec = Self::new(); 34cbd624adSopenharmony_ci vec.try_extend(x)?; 35cbd624adSopenharmony_ci Some(vec) 36cbd624adSopenharmony_ci } 37cbd624adSopenharmony_ci 38cbd624adSopenharmony_ci /// Sets the length of a vector. 39cbd624adSopenharmony_ci /// 40cbd624adSopenharmony_ci /// This will explicitly set the size of the vector, without actually 41cbd624adSopenharmony_ci /// modifying its buffers, so it is up to the caller to ensure that the 42cbd624adSopenharmony_ci /// vector is actually the specified size. 43cbd624adSopenharmony_ci /// 44cbd624adSopenharmony_ci /// # Safety 45cbd624adSopenharmony_ci /// 46cbd624adSopenharmony_ci /// Safe as long as `len` is less than `self.capacity()` and has been initialized. 47cbd624adSopenharmony_ci #[inline] 48cbd624adSopenharmony_ci pub unsafe fn set_len(&mut self, len: usize) { 49cbd624adSopenharmony_ci debug_assert!(len <= bigint::BIGINT_LIMBS); 50cbd624adSopenharmony_ci unsafe { self.data.set_len(len) }; 51cbd624adSopenharmony_ci } 52cbd624adSopenharmony_ci 53cbd624adSopenharmony_ci /// The number of elements stored in the vector. 54cbd624adSopenharmony_ci #[inline] 55cbd624adSopenharmony_ci pub fn len(&self) -> usize { 56cbd624adSopenharmony_ci self.data.len() 57cbd624adSopenharmony_ci } 58cbd624adSopenharmony_ci 59cbd624adSopenharmony_ci /// If the vector is empty. 60cbd624adSopenharmony_ci #[inline] 61cbd624adSopenharmony_ci pub fn is_empty(&self) -> bool { 62cbd624adSopenharmony_ci self.len() == 0 63cbd624adSopenharmony_ci } 64cbd624adSopenharmony_ci 65cbd624adSopenharmony_ci /// The number of items the vector can hold. 66cbd624adSopenharmony_ci #[inline] 67cbd624adSopenharmony_ci pub fn capacity(&self) -> usize { 68cbd624adSopenharmony_ci self.data.capacity() 69cbd624adSopenharmony_ci } 70cbd624adSopenharmony_ci 71cbd624adSopenharmony_ci /// Append an item to the vector. 72cbd624adSopenharmony_ci #[inline] 73cbd624adSopenharmony_ci pub fn try_push(&mut self, value: bigint::Limb) -> Option<()> { 74cbd624adSopenharmony_ci self.data.push(value); 75cbd624adSopenharmony_ci Some(()) 76cbd624adSopenharmony_ci } 77cbd624adSopenharmony_ci 78cbd624adSopenharmony_ci /// Remove an item from the end of the vector and return it, or None if empty. 79cbd624adSopenharmony_ci #[inline] 80cbd624adSopenharmony_ci pub fn pop(&mut self) -> Option<bigint::Limb> { 81cbd624adSopenharmony_ci self.data.pop() 82cbd624adSopenharmony_ci } 83cbd624adSopenharmony_ci 84cbd624adSopenharmony_ci /// Copy elements from a slice and append them to the vector. 85cbd624adSopenharmony_ci #[inline] 86cbd624adSopenharmony_ci pub fn try_extend(&mut self, slc: &[bigint::Limb]) -> Option<()> { 87cbd624adSopenharmony_ci self.data.extend_from_slice(slc); 88cbd624adSopenharmony_ci Some(()) 89cbd624adSopenharmony_ci } 90cbd624adSopenharmony_ci 91cbd624adSopenharmony_ci /// Try to resize the buffer. 92cbd624adSopenharmony_ci /// 93cbd624adSopenharmony_ci /// If the new length is smaller than the current length, truncate 94cbd624adSopenharmony_ci /// the input. If it's larger, then append elements to the buffer. 95cbd624adSopenharmony_ci #[inline] 96cbd624adSopenharmony_ci pub fn try_resize(&mut self, len: usize, value: bigint::Limb) -> Option<()> { 97cbd624adSopenharmony_ci self.data.resize(len, value); 98cbd624adSopenharmony_ci Some(()) 99cbd624adSopenharmony_ci } 100cbd624adSopenharmony_ci 101cbd624adSopenharmony_ci // HI 102cbd624adSopenharmony_ci 103cbd624adSopenharmony_ci /// Get the high 64 bits from the vector. 104cbd624adSopenharmony_ci #[inline(always)] 105cbd624adSopenharmony_ci pub fn hi64(&self) -> (u64, bool) { 106cbd624adSopenharmony_ci bigint::hi64(&self.data) 107cbd624adSopenharmony_ci } 108cbd624adSopenharmony_ci 109cbd624adSopenharmony_ci // FROM 110cbd624adSopenharmony_ci 111cbd624adSopenharmony_ci /// Create StackVec from u64 value. 112cbd624adSopenharmony_ci #[inline(always)] 113cbd624adSopenharmony_ci pub fn from_u64(x: u64) -> Self { 114cbd624adSopenharmony_ci bigint::from_u64(x) 115cbd624adSopenharmony_ci } 116cbd624adSopenharmony_ci 117cbd624adSopenharmony_ci // MATH 118cbd624adSopenharmony_ci 119cbd624adSopenharmony_ci /// Normalize the integer, so any leading zero values are removed. 120cbd624adSopenharmony_ci #[inline] 121cbd624adSopenharmony_ci pub fn normalize(&mut self) { 122cbd624adSopenharmony_ci bigint::normalize(self) 123cbd624adSopenharmony_ci } 124cbd624adSopenharmony_ci 125cbd624adSopenharmony_ci /// Get if the big integer is normalized. 126cbd624adSopenharmony_ci #[inline] 127cbd624adSopenharmony_ci pub fn is_normalized(&self) -> bool { 128cbd624adSopenharmony_ci bigint::is_normalized(self) 129cbd624adSopenharmony_ci } 130cbd624adSopenharmony_ci 131cbd624adSopenharmony_ci /// AddAssign small integer. 132cbd624adSopenharmony_ci #[inline] 133cbd624adSopenharmony_ci pub fn add_small(&mut self, y: bigint::Limb) -> Option<()> { 134cbd624adSopenharmony_ci bigint::small_add(self, y) 135cbd624adSopenharmony_ci } 136cbd624adSopenharmony_ci 137cbd624adSopenharmony_ci /// MulAssign small integer. 138cbd624adSopenharmony_ci #[inline] 139cbd624adSopenharmony_ci pub fn mul_small(&mut self, y: bigint::Limb) -> Option<()> { 140cbd624adSopenharmony_ci bigint::small_mul(self, y) 141cbd624adSopenharmony_ci } 142cbd624adSopenharmony_ci} 143cbd624adSopenharmony_ci 144cbd624adSopenharmony_ciimpl PartialEq for HeapVec { 145cbd624adSopenharmony_ci #[inline] 146cbd624adSopenharmony_ci #[allow(clippy::op_ref)] 147cbd624adSopenharmony_ci fn eq(&self, other: &Self) -> bool { 148cbd624adSopenharmony_ci use core::ops::Deref; 149cbd624adSopenharmony_ci self.len() == other.len() && self.deref() == other.deref() 150cbd624adSopenharmony_ci } 151cbd624adSopenharmony_ci} 152cbd624adSopenharmony_ci 153cbd624adSopenharmony_ciimpl Eq for HeapVec { 154cbd624adSopenharmony_ci} 155cbd624adSopenharmony_ci 156cbd624adSopenharmony_ciimpl cmp::PartialOrd for HeapVec { 157cbd624adSopenharmony_ci #[inline] 158cbd624adSopenharmony_ci fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> { 159cbd624adSopenharmony_ci Some(bigint::compare(self, other)) 160cbd624adSopenharmony_ci } 161cbd624adSopenharmony_ci} 162cbd624adSopenharmony_ci 163cbd624adSopenharmony_ciimpl cmp::Ord for HeapVec { 164cbd624adSopenharmony_ci #[inline] 165cbd624adSopenharmony_ci fn cmp(&self, other: &Self) -> cmp::Ordering { 166cbd624adSopenharmony_ci bigint::compare(self, other) 167cbd624adSopenharmony_ci } 168cbd624adSopenharmony_ci} 169cbd624adSopenharmony_ci 170cbd624adSopenharmony_ciimpl ops::Deref for HeapVec { 171cbd624adSopenharmony_ci type Target = [bigint::Limb]; 172cbd624adSopenharmony_ci #[inline] 173cbd624adSopenharmony_ci fn deref(&self) -> &[bigint::Limb] { 174cbd624adSopenharmony_ci &self.data 175cbd624adSopenharmony_ci } 176cbd624adSopenharmony_ci} 177cbd624adSopenharmony_ci 178cbd624adSopenharmony_ciimpl ops::DerefMut for HeapVec { 179cbd624adSopenharmony_ci #[inline] 180cbd624adSopenharmony_ci fn deref_mut(&mut self) -> &mut [bigint::Limb] { 181cbd624adSopenharmony_ci &mut self.data 182cbd624adSopenharmony_ci } 183cbd624adSopenharmony_ci} 184cbd624adSopenharmony_ci 185cbd624adSopenharmony_ciimpl ops::MulAssign<&[bigint::Limb]> for HeapVec { 186cbd624adSopenharmony_ci #[inline] 187cbd624adSopenharmony_ci fn mul_assign(&mut self, rhs: &[bigint::Limb]) { 188cbd624adSopenharmony_ci bigint::large_mul(self, rhs).unwrap(); 189cbd624adSopenharmony_ci } 190cbd624adSopenharmony_ci} 191