From b7a1f05b1ea492f6fc821b76320facee69457f6f Mon Sep 17 00:00:00 2001 From: Keenan Tims Date: Mon, 16 Dec 2024 14:41:13 -0800 Subject: [PATCH] utils: add misc and implement CustomBounded --- utils/misc/Cargo.lock | 25 ++++++++++++ utils/misc/Cargo.toml | 7 ++++ utils/misc/src/lib.rs | 95 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 127 insertions(+) create mode 100644 utils/misc/Cargo.lock create mode 100644 utils/misc/Cargo.toml create mode 100644 utils/misc/src/lib.rs diff --git a/utils/misc/Cargo.lock b/utils/misc/Cargo.lock new file mode 100644 index 0000000..f6716d7 --- /dev/null +++ b/utils/misc/Cargo.lock @@ -0,0 +1,25 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "misc" +version = "0.1.0" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] diff --git a/utils/misc/Cargo.toml b/utils/misc/Cargo.toml new file mode 100644 index 0000000..3704ff9 --- /dev/null +++ b/utils/misc/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "misc" +version = "0.1.0" +edition = "2021" + +[dependencies] +num-traits = "0.2.19" diff --git a/utils/misc/src/lib.rs b/utils/misc/src/lib.rs new file mode 100644 index 0000000..3aac068 --- /dev/null +++ b/utils/misc/src/lib.rs @@ -0,0 +1,95 @@ +use num_traits::Signed; +use std::ops::{Add, AddAssign}; +use std::fmt::{Debug, Display}; + +/// Wrapped signed integer with custom upper bound with wrapping of 0s to the upper bound +#[derive(Eq, Clone, Copy)] +pub struct CustomWrapped { + pub val: T, + pub bound: T, +} + +impl Add for CustomWrapped { + type Output = CustomWrapped; + fn add(self, rhs: T) -> Self::Output { + Self { + val: ((self.val + rhs % self.bound) + self.bound) % self.bound, + bound: self.bound, + } + } +} + +impl Add for &CustomWrapped { + type Output = CustomWrapped; + fn add(self, rhs: T) -> Self::Output { + CustomWrapped { + val: ((self.val + rhs % self.bound) + self.bound) % self.bound, + bound: self.bound, + } + } +} + +impl AddAssign for CustomWrapped { + fn add_assign(&mut self, rhs: T) { + self.val = ((self.val + rhs % self.bound) + self.bound) % self.bound + } +} + +impl CustomWrapped { + pub fn new(val: T, bound: T) -> Self { + Self { val, bound } + } +} + +impl PartialEq for CustomWrapped { + fn eq(&self, other: &Self) -> bool { + self.val.eq(&other.val) + } +} + +impl PartialOrd for CustomWrapped { + fn partial_cmp(&self, other: &Self) -> Option { + self.val.partial_cmp(&other.val) + } +} + +impl Ord for CustomWrapped { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.val.cmp(&other.val) + } +} + +impl PartialEq for CustomWrapped { + fn eq(&self, other: &T) -> bool { + self.val == *other + } +} + +impl PartialOrd for CustomWrapped { + fn partial_cmp(&self, other: &T) -> Option { + self.val.partial_cmp(other) + } +} + +impl Display for CustomWrapped where T: Display { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.val.fmt(f) + } +} + +// impl Into for CustomWrapped { +// fn into(self) -> T { +// self.val +// } +// } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +}