apply formatting

This commit is contained in:
EvilMuffinHa 2022-08-02 23:37:59 -04:00
parent 5eb006e4c7
commit 9fd27995b2
2 changed files with 60 additions and 60 deletions

View File

@ -5,6 +5,7 @@ edition = "2021"
authors = ["artofrev"] authors = ["artofrev"]
description = "A library for optimized arbitrary precision integers." description = "A library for optimized arbitrary precision integers."
license = "MIT" license = "MIT"
repository = "https://github.com/artofrev/smallint"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

View File

@ -2,26 +2,25 @@
#![warn(clippy::all)] #![warn(clippy::all)]
//! A crate for small integer optimization. Provides the [`SmallInt`] type. When possible this will //! A crate for small integer optimization. Provides the [`SmallInt`] type. When possible this will
//! inline an integer and store it on the stack if that integer is small. However, for larger values, //! inline an integer and store it on the stack if that integer is small. However, for larger values,
//! this will be instead stored on the heap as a pointer to a `u32` slice, a length, and a sign. //! this will be instead stored on the heap as a pointer to a `u32` slice, a length, and a sign.
// Invariant: If a small integer is within the bounds of an inline value, it must be inline. // Invariant: If a small integer is within the bounds of an inline value, it must be inline.
// Invariant: If a small integer is on the heap, the size is the minimum digits required to // Invariant: If a small integer is on the heap, the size is the minimum digits required to
// represent it. // represent it.
#[cfg(feature="num-bigint")] #[cfg(feature = "num-bigint")]
use num_bigint::BigInt; use num_bigint::BigInt;
#[cfg(feature="num-bigint")] #[cfg(feature = "num-bigint")]
use num_bigint::BigUint; use num_bigint::BigUint;
#[cfg(feature="num-bigint")] #[cfg(feature = "num-bigint")]
use num_bigint::Sign; use num_bigint::Sign;
use core::mem::ManuallyDrop; use core::mem::ManuallyDrop;
/// An error that occurred when processing a SmallInt. /// An error that occurred when processing a `SmallInt`.
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub enum SmallIntError { pub enum SmallIntError {
/// Conversion error when converting from SmallInt to other integer types. /// Conversion error when converting from SmallInt to other integer types.
@ -37,32 +36,28 @@ impl core::fmt::Display for SmallIntError {
} }
} }
/// An integer-like type that will store small integers up to `i128` inline. Larger integers are /// An integer-like type that will store small integers up to `i128` inline. Larger integers are
/// represented as a slice to a sequence of base 2<sup>32</sup> digits represented as a `*mut u32`. /// represented as a slice to a sequence of base 2<sup>32</sup> digits represented as a `*mut u32`.
#[derive(Clone, PartialEq, Eq)] #[derive(Clone, PartialEq, Eq)]
pub struct SmallInt(SmallIntType); pub struct SmallInt(SmallIntType);
/// An integer-like type that will store small integers up to `u128` inline. Larger integers are /// An integer-like type that will store small integers up to `u128` inline. Larger integers are
/// represented as a slice to a sequence of base 2<sup>32</sup> digits represented as a `*mut u32`. /// represented as a slice to a sequence of base 2<sup>32</sup> digits represented as a `*mut u32`.
#[derive(Clone, PartialEq, Eq)] #[derive(Clone, PartialEq, Eq)]
pub struct SmallUint(SmallUintType); pub struct SmallUint(SmallUintType);
#[derive(Clone, PartialEq, Eq)] #[derive(Clone, PartialEq, Eq)]
enum SmallIntType { enum SmallIntType {
Inline(i128), Inline(i128),
Heap((*mut u32, isize)) Heap((*mut u32, isize)),
} }
#[derive(Clone, PartialEq, Eq)] #[derive(Clone, PartialEq, Eq)]
enum SmallUintType { enum SmallUintType {
Inline(u128), Inline(u128),
Heap((*mut u32, usize)) Heap((*mut u32, usize)),
} }
impl Drop for SmallInt { impl Drop for SmallInt {
fn drop(&mut self) { fn drop(&mut self) {
if let Self(SmallIntType::Heap((r, s))) = self { if let Self(SmallIntType::Heap((r, s))) = self {
@ -71,7 +66,6 @@ impl Drop for SmallInt {
unsafe { std::mem::drop(Box::from_raw(slice)) } unsafe { std::mem::drop(Box::from_raw(slice)) }
} }
} }
} }
impl Drop for SmallUint { impl Drop for SmallUint {
@ -81,7 +75,6 @@ impl Drop for SmallUint {
unsafe { std::mem::drop(Box::from_raw(slice)) } unsafe { std::mem::drop(Box::from_raw(slice)) }
} }
} }
} }
macro_rules! int_impl { macro_rules! int_impl {
@ -93,58 +86,61 @@ macro_rules! int_impl {
} }
impl TryFrom<$rt> for $itype { impl TryFrom<$rt> for $itype {
type Error = SmallIntError; type Error = SmallIntError;
fn try_from(s: $rt) -> Result<Self, Self::Error> { fn try_from(s: $rt) -> Result<Self, Self::Error> {
match s.0 { match s.0 {
$rtt::Inline(i) => <$itype>::try_from(i).map_err(|_| SmallIntError::ConversionError), $rtt::Inline(i) => {
<$itype>::try_from(i).map_err(|_| SmallIntError::ConversionError)
}
$rtt::Heap((_, _)) => Err(SmallIntError::ConversionError), $rtt::Heap((_, _)) => Err(SmallIntError::ConversionError),
} }
} }
} }
} };
} }
int_impl!(u8, SmallInt, SmallIntType, i128); int_impl!(u8, SmallInt, SmallIntType, i128);
int_impl!(u16, SmallInt, SmallIntType, i128); int_impl!(u16, SmallInt, SmallIntType, i128);
int_impl!(u32, SmallInt, SmallIntType, i128); int_impl!(u32, SmallInt, SmallIntType, i128);
int_impl!(u64, SmallInt, SmallIntType, i128); int_impl!(u64, SmallInt, SmallIntType, i128);
int_impl!(i8, SmallInt, SmallIntType, i128); int_impl!(i8, SmallInt, SmallIntType, i128);
int_impl!(i16, SmallInt, SmallIntType, i128); int_impl!(i16, SmallInt, SmallIntType, i128);
int_impl!(i32, SmallInt, SmallIntType, i128); int_impl!(i32, SmallInt, SmallIntType, i128);
int_impl!(i64, SmallInt, SmallIntType, i128); int_impl!(i64, SmallInt, SmallIntType, i128);
int_impl!(i128, SmallInt, SmallIntType, i128); int_impl!(i128, SmallInt, SmallIntType, i128);
int_impl!(u8, SmallUint, SmallUintType, u128); int_impl!(u8, SmallUint, SmallUintType, u128);
int_impl!(u16, SmallUint, SmallUintType, u128); int_impl!(u16, SmallUint, SmallUintType, u128);
int_impl!(u32, SmallUint, SmallUintType, u128); int_impl!(u32, SmallUint, SmallUintType, u128);
int_impl!(u64, SmallUint, SmallUintType, u128); int_impl!(u64, SmallUint, SmallUintType, u128);
int_impl!(u128, SmallUint, SmallUintType, u128); int_impl!(u128, SmallUint, SmallUintType, u128);
macro_rules! try_from_itou { macro_rules! try_from_itou {
($itype:ty) => { ($itype:ty) => {
impl TryFrom<$itype> for SmallUint { impl TryFrom<$itype> for SmallUint {
type Error = SmallIntError; type Error = SmallIntError;
fn try_from(a: $itype) -> Result<Self, Self::Error> { fn try_from(a: $itype) -> Result<Self, Self::Error> {
Ok(Self(SmallUintType::Inline(u128::try_from(a).map_err(|_| SmallIntError::ConversionError)?))) Ok(Self(SmallUintType::Inline(
u128::try_from(a).map_err(|_| SmallIntError::ConversionError)?,
)))
} }
} }
impl TryFrom<SmallUint> for $itype { impl TryFrom<SmallUint> for $itype {
type Error = SmallIntError; type Error = SmallIntError;
fn try_from(s: SmallUint) -> Result<Self, Self::Error> { fn try_from(s: SmallUint) -> Result<Self, Self::Error> {
match s.0 { match s.0 {
SmallUintType::Inline(i) => <$itype>::try_from(i).map_err(|_| SmallIntError::ConversionError), SmallUintType::Inline(i) => {
<$itype>::try_from(i).map_err(|_| SmallIntError::ConversionError)
}
SmallUintType::Heap((_, _)) => Err(SmallIntError::ConversionError), SmallUintType::Heap((_, _)) => Err(SmallIntError::ConversionError),
} }
} }
} }
} };
} }
try_from_itou!(i8); try_from_itou!(i8);
@ -153,7 +149,6 @@ try_from_itou!(i32);
try_from_itou!(i64); try_from_itou!(i64);
try_from_itou!(i128); try_from_itou!(i128);
impl From<u128> for SmallInt { impl From<u128> for SmallInt {
fn from(a: u128) -> Self { fn from(a: u128) -> Self {
match i128::try_from(a) { match i128::try_from(a) {
@ -167,19 +162,23 @@ impl From<u128> for SmallInt {
v >>= 32; v >>= 32;
} }
let mut slice = ManuallyDrop::new(vec.into_boxed_slice()); let mut slice = ManuallyDrop::new(vec.into_boxed_slice());
Self(SmallIntType::Heap((slice.as_mut_ptr(), isize::try_from(slice.len()).unwrap()))) Self(SmallIntType::Heap((
slice.as_mut_ptr(),
isize::try_from(slice.len()).unwrap(),
)))
} }
} }
} }
} }
impl TryFrom<SmallInt> for u128 { impl TryFrom<SmallInt> for u128 {
type Error = SmallIntError; type Error = SmallIntError;
fn try_from(s: SmallInt) -> Result<Self, Self::Error> { fn try_from(s: SmallInt) -> Result<Self, Self::Error> {
match s.0 { match s.0 {
SmallIntType::Inline(i) => u128::try_from(i).map_err(|_| SmallIntError::ConversionError), SmallIntType::Inline(i) => {
u128::try_from(i).map_err(|_| SmallIntError::ConversionError)
}
SmallIntType::Heap((r, s)) => { SmallIntType::Heap((r, s)) => {
let mut ret: u128 = 0; let mut ret: u128 = 0;
let mut bits = 0; let mut bits = 0;
@ -203,14 +202,14 @@ impl From<SmallUint> for SmallInt {
fn from(s: SmallUint) -> Self { fn from(s: SmallUint) -> Self {
match s.0 { match s.0 {
SmallUintType::Inline(i) => SmallInt::from(i), SmallUintType::Inline(i) => SmallInt::from(i),
SmallUintType::Heap((r, s)) => SmallInt(SmallIntType::Heap((r, isize::try_from(s).unwrap()))) SmallUintType::Heap((r, s)) => {
SmallInt(SmallIntType::Heap((r, isize::try_from(s).unwrap())))
}
} }
} }
} }
impl TryFrom<SmallInt> for SmallUint { impl TryFrom<SmallInt> for SmallUint {
type Error = SmallIntError; type Error = SmallIntError;
fn try_from(value: SmallInt) -> Result<Self, Self::Error> { fn try_from(value: SmallInt) -> Result<Self, Self::Error> {
@ -226,11 +225,9 @@ impl TryFrom<SmallInt> for SmallUint {
} }
} }
} }
} }
#[cfg(feature = "num-bigint")]
#[cfg(feature="num-bigint")]
impl From<BigInt> for SmallInt { impl From<BigInt> for SmallInt {
fn from(b: BigInt) -> Self { fn from(b: BigInt) -> Self {
match (&b).try_into() { match (&b).try_into() {
@ -240,15 +237,18 @@ impl From<BigInt> for SmallInt {
let mut slice = ManuallyDrop::new(vec.into_boxed_slice()); let mut slice = ManuallyDrop::new(vec.into_boxed_slice());
let size = match sign { let size = match sign {
Sign::Minus => -isize::try_from(slice.len()).unwrap(), Sign::Minus => -isize::try_from(slice.len()).unwrap(),
Sign::NoSign => panic!("Shouldn't happen; BigInts which store zero should convert to inline."), Sign::NoSign => panic!(
Sign::Plus => isize::try_from(slice.len()).unwrap() "Shouldn't happen; BigInts which store zero should convert to inline."
),
Sign::Plus => isize::try_from(slice.len()).unwrap(),
}; };
Self(SmallIntType::Heap((slice.as_mut_ptr(), size))) } Self(SmallIntType::Heap((slice.as_mut_ptr(), size)))
}
} }
} }
} }
#[cfg(feature="num-bigint")] #[cfg(feature = "num-bigint")]
impl From<SmallInt> for BigInt { impl From<SmallInt> for BigInt {
fn from(s: SmallInt) -> Self { fn from(s: SmallInt) -> Self {
match s.0 { match s.0 {
@ -270,7 +270,7 @@ impl From<SmallInt> for BigInt {
} }
} }
#[cfg(feature="num-bigint")] #[cfg(feature = "num-bigint")]
impl From<BigUint> for SmallUint { impl From<BigUint> for SmallUint {
fn from(b: BigUint) -> Self { fn from(b: BigUint) -> Self {
match (&b).try_into() { match (&b).try_into() {
@ -279,12 +279,13 @@ impl From<BigUint> for SmallUint {
let vec = b.to_u32_digits(); let vec = b.to_u32_digits();
let mut slice = ManuallyDrop::new(vec.into_boxed_slice()); let mut slice = ManuallyDrop::new(vec.into_boxed_slice());
let size = slice.len(); let size = slice.len();
Self(SmallUintType::Heap((slice.as_mut_ptr(), size))) } Self(SmallUintType::Heap((slice.as_mut_ptr(), size)))
}
} }
} }
} }
#[cfg(feature="num-bigint")] #[cfg(feature = "num-bigint")]
impl From<SmallUint> for BigUint { impl From<SmallUint> for BigUint {
fn from(s: SmallUint) -> Self { fn from(s: SmallUint) -> Self {
match s.0 { match s.0 {
@ -298,14 +299,12 @@ impl From<SmallUint> for BigUint {
} }
} }
#[cfg(test)] #[cfg(test)]
mod conversion_tests { mod conversion_tests {
use crate::SmallInt; use crate::SmallInt;
#[cfg(feature="num-bigint")] #[cfg(feature = "num-bigint")]
use num_bigint::{BigInt, Sign}; use num_bigint::{BigInt, Sign};
macro_rules! conversion_tests { macro_rules! conversion_tests {
@ -320,8 +319,7 @@ mod conversion_tests {
let s = SmallInt::from(i); let s = SmallInt::from(i);
assert_eq!(<$t>::try_from(s).unwrap(), i); assert_eq!(<$t>::try_from(s).unwrap(), i);
} }
};
}
} }
conversion_tests!(u8, test_u8); conversion_tests!(u8, test_u8);
@ -336,12 +334,13 @@ mod conversion_tests {
conversion_tests!(i128, test_i128); conversion_tests!(i128, test_i128);
#[test] #[test]
#[cfg(feature="num-bigint")] #[cfg(feature = "num-bigint")]
fn test_bigint() { fn test_bigint() {
let i = BigInt::new(Sign::Plus, vec![5, 4, 8, 3, 2, 9, 3]); let i = BigInt::new(Sign::Plus, vec![5, 4, 8, 3, 2, 9, 3]);
let s = SmallInt::from(i); let s = SmallInt::from(i);
assert_eq!(BigInt::from(s).to_u32_digits(), (Sign::Plus, vec![5, 4, 8, 3, 2, 9, 3])); assert_eq!(
BigInt::from(s).to_u32_digits(),
(Sign::Plus, vec![5, 4, 8, 3, 2, 9, 3])
);
} }
} }