summaryrefslogtreecommitdiffstats
path: root/third_party/rust/minimal-lexical/src/heapvec.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/minimal-lexical/src/heapvec.rs')
-rw-r--r--third_party/rust/minimal-lexical/src/heapvec.rs190
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();
+ }
+}