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