usecrate::bigint; use core::{cmp, mem, ops, ptr, slice};
/// Simple stack vector implementation. #[derive(Clone)] pubstruct StackVec { /// The raw buffer for the elements.
data: [mem::MaybeUninit<bigint::Limb>; bigint::BIGINT_LIMBS], /// The number of elements in the array (we never need more than u16::MAX).
length: u16,
}
/// Construct a vector from an existing slice. #[inline] pubfn try_from(x: &[bigint::Limb]) -> Option<Self> { letmut 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 `BIGINT_LIMBS`. #[inline] pubunsafefn set_len(&mutself, len: usize) { // Constant is `u16::MAX` for older Rustc versions.
debug_assert!(len <= 0xffff);
debug_assert!(len <= bigint::BIGINT_LIMBS); self.length = len as u16;
}
/// The number of elements stored in the vector. #[inline] pubconstfn len(&self) -> usize { self.length as usize
}
/// If the vector is empty. #[inline] pubconstfn is_empty(&self) -> bool { self.len() == 0
}
/// The number of items the vector can hold. #[inline] pubconstfn capacity(&self) -> usize {
bigint::BIGINT_LIMBS as usize
}
/// Append an item to the vector, without bounds checking. /// /// # Safety /// /// Safe if `self.len() < self.capacity()`. #[inline] pubunsafefn push_unchecked(&mutself, value: bigint::Limb) {
debug_assert!(self.len() < self.capacity()); // SAFETY: safe, capacity is less than the current size. unsafe {
ptr::write(self.as_mut_ptr().add(self.len()), value); self.length += 1;
}
}
/// Append an item to the vector. #[inline] pubfn try_push(&mutself, value: bigint::Limb) -> Option<()> { ifself.len() < self.capacity() { // SAFETY: safe, capacity is less than the current size. unsafe { self.push_unchecked(value) };
Some(())
} else {
None
}
}
/// Remove an item from the end of a vector, without bounds checking. /// /// # Safety /// /// Safe if `self.len() > 0`. #[inline] pubunsafefn pop_unchecked(&mutself) -> bigint::Limb {
debug_assert!(!self.is_empty()); // SAFETY: safe if `self.length > 0`. // We have a trivial drop and copy, so this is safe. self.length -= 1; unsafe { ptr::read(self.as_mut_ptr().add(self.len())) }
}
/// Remove an item from the end of the vector and return it, or None if empty. #[inline] pubfn pop(&mutself) -> Option<bigint::Limb> { ifself.is_empty() {
None
} else { // SAFETY: safe, since `self.len() > 0`. unsafe { Some(self.pop_unchecked()) }
}
}
/// Add items from a slice to the vector, without bounds checking. /// /// # Safety /// /// Safe if `self.len() + slc.len() <= self.capacity()`. #[inline] pubunsafefn extend_unchecked(&mutself, slc: &[bigint::Limb]) { let index = self.len(); let new_len = index + slc.len();
debug_assert!(self.len() + slc.len() <= self.capacity()); let src = slc.as_ptr(); // SAFETY: safe if `self.len() + slc.len() <= self.capacity()`. unsafe { let dst = self.as_mut_ptr().add(index);
ptr::copy_nonoverlapping(src, dst, slc.len()); self.set_len(new_len);
}
}
/// Copy elements from a slice and append them to the vector. #[inline] pubfn try_extend(&mutself, slc: &[bigint::Limb]) -> Option<()> { ifself.len() + slc.len() <= self.capacity() { // SAFETY: safe, since `self.len() + slc.len() <= self.capacity()`. unsafe { self.extend_unchecked(slc) };
Some(())
} else {
None
}
}
/// Truncate vector to new length, dropping any items after `len`. /// /// # Safety /// /// Safe as long as `len <= self.capacity()`. unsafefn truncate_unchecked(&mutself, len: usize) {
debug_assert!(len <= self.capacity()); self.length = len as u16;
}
/// Resize the buffer, without bounds checking. /// /// # Safety /// /// Safe as long as `len <= self.capacity()`. #[inline] pubunsafefn resize_unchecked(&mutself, len: usize, value: bigint::Limb) {
debug_assert!(len <= self.capacity()); let old_len = self.len(); if len > old_len { // We have a trivial drop, so there's no worry here. // Just, don't set the length until all values have been written, // so we don't accidentally read uninitialized memory.
// SAFETY: safe if `len < self.capacity()`. let count = len - old_len; for index in0..count { unsafe { let dst = self.as_mut_ptr().add(old_len + index);
ptr::write(dst, value);
}
} self.length = len as u16;
} else { // SAFETY: safe since `len < self.len()`. unsafe { self.truncate_unchecked(len) };
}
}
/// 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] pubfn try_resize(&mutself, len: usize, value: bigint::Limb) -> Option<()> { if len > self.capacity() {
None
} else { // SAFETY: safe, since `len <= self.capacity()`. unsafe { self.resize_unchecked(len, value) };
Some(())
}
}
// HI
/// Get the high 64 bits from the vector. #[inline(always)] pubfn hi64(&self) -> (u64, bool) {
bigint::hi64(self)
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.