diff options
Diffstat (limited to 'third_party/rust/minimal-lexical/src/heapvec.rs')
-rw-r--r-- | third_party/rust/minimal-lexical/src/heapvec.rs | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/third_party/rust/minimal-lexical/src/heapvec.rs b/third_party/rust/minimal-lexical/src/heapvec.rs new file mode 100644 index 0000000000..035926018a --- /dev/null +++ b/third_party/rust/minimal-lexical/src/heapvec.rs @@ -0,0 +1,190 @@ +//! Simple heap-allocated vector. + +#![cfg(feature = "alloc")] +#![doc(hidden)] + +use crate::bigint; +#[cfg(not(feature = "std"))] +use alloc::vec::Vec; +use core::{cmp, ops}; +#[cfg(feature = "std")] +use std::vec::Vec; + +/// Simple heap vector implementation. +#[derive(Clone)] +pub struct HeapVec { + /// The heap-allocated buffer for the elements. + data: Vec<bigint::Limb>, +} + +#[allow(clippy::new_without_default)] +impl HeapVec { + /// Construct an empty vector. + #[inline] + pub fn new() -> Self { + Self { + data: Vec::with_capacity(bigint::BIGINT_LIMBS), + } + } + + /// Construct a vector from an existing slice. + #[inline] + pub fn try_from(x: &[bigint::Limb]) -> Option<Self> { + let mut vec = Self::new(); + vec.try_extend(x)?; + Some(vec) + } + + /// Sets the length of a vector. + /// + /// This will explicitly set the size of the vector, without actually + /// modifying its buffers, so it is up to the caller to ensure that the + /// vector is actually the specified size. + /// + /// # Safety + /// + /// Safe as long as `len` is less than `self.capacity()` and has been initialized. + #[inline] + pub unsafe fn set_len(&mut self, len: usize) { + debug_assert!(len <= bigint::BIGINT_LIMBS); + unsafe { self.data.set_len(len) }; + } + + /// The number of elements stored in the vector. + #[inline] + pub fn len(&self) -> usize { + self.data.len() + } + + /// If the vector is empty. + #[inline] + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + /// The number of items the vector can hold. + #[inline] + pub fn capacity(&self) -> usize { + self.data.capacity() + } + + /// Append an item to the vector. + #[inline] + pub fn try_push(&mut self, value: bigint::Limb) -> Option<()> { + self.data.push(value); + Some(()) + } + + /// Remove an item from the end of the vector and return it, or None if empty. + #[inline] + pub fn pop(&mut self) -> Option<bigint::Limb> { + self.data.pop() + } + + /// Copy elements from a slice and append them to the vector. + #[inline] + pub fn try_extend(&mut self, slc: &[bigint::Limb]) -> Option<()> { + self.data.extend_from_slice(slc); + Some(()) + } + + /// Try to resize the buffer. + /// + /// If the new length is smaller than the current length, truncate + /// the input. If it's larger, then append elements to the buffer. + #[inline] + pub fn try_resize(&mut self, len: usize, value: bigint::Limb) -> Option<()> { + self.data.resize(len, value); + Some(()) + } + + // HI + + /// Get the high 64 bits from the vector. + #[inline(always)] + pub fn hi64(&self) -> (u64, bool) { + bigint::hi64(&self.data) + } + + // FROM + + /// Create StackVec from u64 value. + #[inline(always)] + pub fn from_u64(x: u64) -> Self { + bigint::from_u64(x) + } + + // MATH + + /// Normalize the integer, so any leading zero values are removed. + #[inline] + pub fn normalize(&mut self) { + bigint::normalize(self) + } + + /// Get if the big integer is normalized. + #[inline] + pub fn is_normalized(&self) -> bool { + bigint::is_normalized(self) + } + + /// AddAssign small integer. + #[inline] + pub fn add_small(&mut self, y: bigint::Limb) -> Option<()> { + bigint::small_add(self, y) + } + + /// MulAssign small integer. + #[inline] + pub fn mul_small(&mut self, y: bigint::Limb) -> Option<()> { + bigint::small_mul(self, y) + } +} + +impl PartialEq for HeapVec { + #[inline] + #[allow(clippy::op_ref)] + fn eq(&self, other: &Self) -> bool { + use core::ops::Deref; + self.len() == other.len() && self.deref() == other.deref() + } +} + +impl Eq for HeapVec { +} + +impl cmp::PartialOrd for HeapVec { + #[inline] + fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> { + Some(bigint::compare(self, other)) + } +} + +impl cmp::Ord for HeapVec { + #[inline] + fn cmp(&self, other: &Self) -> cmp::Ordering { + bigint::compare(self, other) + } +} + +impl ops::Deref for HeapVec { + type Target = [bigint::Limb]; + #[inline] + fn deref(&self) -> &[bigint::Limb] { + &self.data + } +} + +impl ops::DerefMut for HeapVec { + #[inline] + fn deref_mut(&mut self) -> &mut [bigint::Limb] { + &mut self.data + } +} + +impl ops::MulAssign<&[bigint::Limb]> for HeapVec { + #[inline] + fn mul_assign(&mut self, rhs: &[bigint::Limb]) { + bigint::large_mul(self, rhs).unwrap(); + } +} |