diff options
| author | superwhiskers <[email protected]> | 2025-09-15 13:38:14 -0500 |
|---|---|---|
| committer | superwhiskers <[email protected]> | 2026-01-04 22:23:01 -0600 |
| commit | e12b1f4459aee80ee333e90e3b56a3b09f81ae3e (patch) | |
| tree | 872402360b490c992bb0d7e071ab2834adeae03e /crates/core/src/utilities.rs | |
| parent | 50192cbe91da765d3c09cf8e12f328b721d3cb46 (diff) | |
| download | azimuth-e12b1f4459aee80ee333e90e3b56a3b09f81ae3e.tar.gz azimuth-e12b1f4459aee80ee333e90e3b56a3b09f81ae3e.tar.bz2 azimuth-e12b1f4459aee80ee333e90e3b56a3b09f81ae3e.zip | |
node topological sorting
Change-Id: I6a6a6964255d818be1bf9a8f4ec9e317befa19c5
Diffstat (limited to 'crates/core/src/utilities.rs')
| -rw-r--r-- | crates/core/src/utilities.rs | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/crates/core/src/utilities.rs b/crates/core/src/utilities.rs new file mode 100644 index 0000000..583ad7c --- /dev/null +++ b/crates/core/src/utilities.rs @@ -0,0 +1,190 @@ +//! Utilities used throughout the library. + +use alloc::{alloc::Allocator, collections::TryReserveError, vec::Vec}; + +#[cfg(feature = "core-fmt")] +use core::fmt; + +#[cfg(feature = "core-error")] +use core::error; + +/// Extension trait for handling OOM conditions better with a [`Vec`]. +pub trait VecMemoryExt<T> { + /// Appends an element to the back of the vector. + /// + /// # Errors + /// + /// This method errors if the capacity overflows or if the allocator + /// reports a failure. + fn try_push(&mut self, value: T) -> Result<(), TryReserveError>; +} + +impl<T, A> VecMemoryExt<T> for Vec<T, A> +where + A: Allocator, +{ + fn try_push(&mut self, value: T) -> Result<(), TryReserveError> { + self.try_reserve(1)?; + + //SAFETY: we just reserved space for this element + unsafe { self.push_within_capacity(value).unwrap_unchecked() }; + + Ok(()) + } +} + +/// Extension trait for wrapping arithmetic. +pub trait WrappingArithmeticExt { + /// Wrapping integer increment. + fn wrapping_increment(self) -> Self; + + /// Mutable wrapping integer increment. + fn wrapping_increment_mut(&mut self); + + /// Wrapping integer decrement. + fn wrapping_decrement(self) -> Self; + + /// Mutable wrapping integer decrement. + fn wrapping_decrement_mut(&mut self); +} + +macro_rules! wrapping_arithmetic_ext_impl { + ($t:ty) => { + impl WrappingArithmeticExt for $t { + fn wrapping_increment(self) -> Self { + self.wrapping_add(1) + } + + fn wrapping_increment_mut(&mut self) { + *self = self.wrapping_add(1); + } + + fn wrapping_decrement(self) -> Self { + self.wrapping_sub(1) + } + + fn wrapping_decrement_mut(&mut self) { + *self = self.wrapping_sub(1); + } + } + }; +} + +wrapping_arithmetic_ext_impl!(usize); +wrapping_arithmetic_ext_impl!(u64); +wrapping_arithmetic_ext_impl!(u32); +wrapping_arithmetic_ext_impl!(u16); +wrapping_arithmetic_ext_impl!(u8); + +wrapping_arithmetic_ext_impl!(isize); +wrapping_arithmetic_ext_impl!(i64); +wrapping_arithmetic_ext_impl!(i32); +wrapping_arithmetic_ext_impl!(i16); +wrapping_arithmetic_ext_impl!(i8); + +/// Extension trait for checked arithmetic that turns the output into a +/// [`Result`]. +pub trait CheckedArithmeticExt: Sized { + /// Checked integer addition. + /// + /// # Errors + /// + /// Returns an error if the result would have overflowed. + fn errored_add(self, rhs: Self) -> Result<Self, IntegerOverflowError>; + + /// Checked integer division. + /// + /// # Errors + /// + /// Returns an error if the result would have overflowed. + fn errored_div(self, rhs: Self) -> Result<Self, IntegerOverflowError>; + + /// Checked integer multiplication. + /// + /// # Errors + /// + /// Returns an error if the result would have overflowed. + fn errored_mul(self, rhs: Self) -> Result<Self, IntegerOverflowError>; + + /// Checked integer remainder. + /// + /// # Errors + /// + /// Returns an error if the result would have overflowed. + fn errored_rem(self, rhs: Self) -> Result<Self, IntegerOverflowError>; + + /// Checked integer subtraction. + /// + /// # Errors + /// + /// Returns an error if the result would have overflowed. + fn errored_sub(self, rhs: Self) -> Result<Self, IntegerOverflowError>; +} + +macro_rules! checked_arithmetic_ext_impl { + ($t:ty) => { + impl CheckedArithmeticExt for $t { + fn errored_add( + self, + rhs: Self, + ) -> Result<Self, IntegerOverflowError> { + self.checked_add(rhs).ok_or(IntegerOverflowError) + } + + fn errored_div( + self, + rhs: Self, + ) -> Result<Self, IntegerOverflowError> { + self.checked_div(rhs).ok_or(IntegerOverflowError) + } + + fn errored_mul( + self, + rhs: Self, + ) -> Result<Self, IntegerOverflowError> { + self.checked_mul(rhs).ok_or(IntegerOverflowError) + } + + fn errored_rem( + self, + rhs: Self, + ) -> Result<Self, IntegerOverflowError> { + self.checked_rem(rhs).ok_or(IntegerOverflowError) + } + + fn errored_sub( + self, + rhs: Self, + ) -> Result<Self, IntegerOverflowError> { + self.checked_sub(rhs).ok_or(IntegerOverflowError) + } + } + }; +} + +checked_arithmetic_ext_impl!(usize); +checked_arithmetic_ext_impl!(u64); +checked_arithmetic_ext_impl!(u32); +checked_arithmetic_ext_impl!(u16); +checked_arithmetic_ext_impl!(u8); + +checked_arithmetic_ext_impl!(isize); +checked_arithmetic_ext_impl!(i64); +checked_arithmetic_ext_impl!(i32); +checked_arithmetic_ext_impl!(i16); +checked_arithmetic_ext_impl!(i8); + +/// Representation of an integer overflow error. +#[derive(PartialEq, Eq)] +#[cfg_attr(feature = "core-fmt", derive(Debug))] +pub struct IntegerOverflowError; + +#[cfg(feature = "core-fmt")] +impl fmt::Display for IntegerOverflowError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("integer overflow") + } +} + +#[cfg(feature = "core-error")] +impl error::Error for IntegerOverflowError {} |
