Skip to content

Commit

Permalink
feat: alloc feature
Browse files Browse the repository at this point in the history
  • Loading branch information
DaniPopes committed Jul 27, 2023
1 parent e34200e commit 6d4dfd9
Show file tree
Hide file tree
Showing 12 changed files with 153 additions and 130 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Support for `no_std` environments (#274)
- Support for `no_std` environments ([#274])
- `alloc` feature ([#277])

[#274]: https://github.com/recmo/uint/pulls/274
[#277]: https://github.com/recmo/uint/pulls/277

## [1.9.0] - 2023-07-25

Expand Down
17 changes: 10 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ required-features = ["std"]

[dependencies]
ruint-macro.workspace = true
itoa = "1.0"

thiserror = { version = "1.0", optional = true }

Expand All @@ -51,7 +52,7 @@ arbitrary = { version = "1", optional = true, default-features = false }
ark-ff-03 = { version = "0.3.0", package = "ark-ff", optional = true, default-features = false }
ark-ff-04 = { version = "0.4.0", package = "ark-ff", optional = true, default-features = false }
bn-rs = { version = "0.2", optional = true, default-features = true }
fastrlp = { version = "0.3", optional = true, default-features = false }
fastrlp = { version = "0.3", optional = true, default-features = false, features = ["alloc"] }
num-bigint = { version = "0.4", optional = true, default-features = false }
parity-scale-codec = { version = "3", optional = true, features = [
"derive",
Expand Down Expand Up @@ -93,8 +94,9 @@ proptest = "1.2"
serde_json = "1.0"

[features]
default = ["std"]
# default = ["std"]
std = [
"alloc",
"alloy-rlp?/std",
"ark-ff-03?/std",
"ark-ff-04?/std",
Expand All @@ -110,22 +112,23 @@ std = [
"valuable?/std",
"zeroize?/std",
]
alloc = ["proptest?/alloc", "rand?/alloc", "serde?/alloc", "valuable?/alloc", "zeroize?/alloc"]

# nightly-only features
nightly = []
generic_const_exprs = ["nightly"]

# support
alloy-rlp = ["dep:alloy-rlp"]
alloy-rlp = ["dep:alloy-rlp", "alloc"]
arbitrary = ["dep:arbitrary", "std"]
ark-ff = ["dep:ark-ff-03"]
ark-ff-04 = ["dep:ark-ff-04"]
bn-rs = ["dep:bn-rs", "std"]
fastrlp = ["dep:fastrlp"]
num-bigint = ["dep:num-bigint"]
parity-scale-codec = ["dep:parity-scale-codec"]
fastrlp = ["dep:fastrlp", "alloc"]
num-bigint = ["dep:num-bigint", "alloc"]
parity-scale-codec = ["dep:parity-scale-codec", "alloc"]
primitive-types = ["dep:primitive-types"]
proptest = ["dep:proptest"]
proptest = ["dep:proptest", "alloc"]
pyo3 = ["dep:pyo3", "std"]
quickcheck = ["dep:quickcheck", "std"]
rand = ["dep:rand"]
Expand Down
2 changes: 0 additions & 2 deletions src/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ impl<const BITS: usize, const LIMBS: usize> Uint<BITS, LIMBS> {
}
}

#[allow(clippy::doc_markdown)]
/// Calculates $\mod{\mathtt{self} + \mathtt{rhs}}_{2^{BITS}}$.
///
/// Returns a tuple of the addition along with a boolean indicating whether
Expand Down Expand Up @@ -88,7 +87,6 @@ impl<const BITS: usize, const LIMBS: usize> Uint<BITS, LIMBS> {
Self::ZERO.overflowing_sub(self)
}

#[allow(clippy::doc_markdown)]
/// Calculates $\mod{\mathtt{self} - \mathtt{rhs}}_{2^{BITS}}$.
///
/// Returns a tuple of the subtraction along with a boolean indicating
Expand Down
4 changes: 3 additions & 1 deletion src/algorithms/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ mod add;
pub mod div;
mod gcd;
mod mul;
#[cfg(feature = "alloc")] // TODO: Make mul_redc alloc-free
mod mul_redc;
mod ops;
mod shift;
Expand All @@ -16,10 +17,11 @@ pub use self::{
div::div,
gcd::{gcd, gcd_extended, inv_mod, LehmerMatrix},
mul::{add_nx1, addmul, addmul_n, addmul_nx1, addmul_ref, submul_nx1},
mul_redc::mul_redc,
ops::{adc, sbb},
shift::{shift_left_small, shift_right_small},
};
#[cfg(feature = "alloc")]
pub use mul_redc::mul_redc;

trait DoubleWord<T>: Sized + Copy {
fn join(high: T, low: T) -> Self;
Expand Down
49 changes: 25 additions & 24 deletions src/base_convert.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::Uint;
use alloc::vec::Vec;
use core::fmt;

/// Error for [`from_base_le`][Uint::from_base_le] and
Expand Down Expand Up @@ -45,6 +44,7 @@ impl<const BITS: usize, const LIMBS: usize> Uint<BITS, LIMBS> {
/// # Panics
///
/// Panics if the base is less than 2.
#[inline]
pub fn to_base_le(&self, base: u64) -> impl Iterator<Item = u64> {
assert!(base > 1);
SpigotLittle {
Expand All @@ -63,9 +63,23 @@ impl<const BITS: usize, const LIMBS: usize> Uint<BITS, LIMBS> {
/// # Panics
///
/// Panics if the base is less than 2.
#[inline]
#[cfg(feature = "alloc")] // OPT: Find an allocation free method. Maybe extract from the top?
pub fn to_base_be(&self, base: u64) -> impl Iterator<Item = u64> {
struct OwnedVecIterator {
vec: alloc::vec::Vec<u64>,
}

impl Iterator for OwnedVecIterator {
type Item = u64;

#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.vec.pop()
}
}

assert!(base > 1);
// OPT: Find an allocation free method. Maybe extract from the top?
OwnedVecIterator {
vec: self.to_base_le(base).collect(),
}
Expand All @@ -79,14 +93,13 @@ impl<const BITS: usize, const LIMBS: usize> Uint<BITS, LIMBS> {
/// * [`BaseConvertError::InvalidDigit`] if a digit is out of range.
/// * [`BaseConvertError::Overflow`] if the number is too large to
/// fit.
pub fn from_base_le<I: IntoIterator<Item = u64>>(
base: u64,
digits: I,
) -> Result<Self, BaseConvertError> {
// TODO: Do not allocate.
let mut digits: Vec<_> = digits.into_iter().collect();
digits.reverse();
Self::from_base_be(base, digits)
#[inline]
pub fn from_base_le<I>(base: u64, digits: I) -> Result<Self, BaseConvertError>
where
I: IntoIterator<Item = u64>,
I::IntoIter: DoubleEndedIterator,
{
Self::from_base_be(base, digits.into_iter().rev())
}

/// Constructs the [`Uint`] from digits in the base `base` in big-endian.
Expand Down Expand Up @@ -139,6 +152,7 @@ struct SpigotLittle<const LIMBS: usize> {
impl<const LIMBS: usize> Iterator for SpigotLittle<LIMBS> {
type Item = u64;

#[inline]
#[allow(clippy::cast_possible_truncation)] // Doesn't truncate
fn next(&mut self) -> Option<Self::Item> {
// Knuth Algorithm S.
Expand All @@ -147,8 +161,7 @@ impl<const LIMBS: usize> Iterator for SpigotLittle<LIMBS> {
// OPT: If we keep track of leading zero limbs we can half iterations.
for limb in self.limbs.iter_mut().rev() {
zero |= *limb;
remainder <<= 64;
remainder |= u128::from(*limb);
remainder = (remainder << 64) | u128::from(*limb);
*limb = (remainder / u128::from(self.base)) as u64;
remainder %= u128::from(self.base);
}
Expand All @@ -160,18 +173,6 @@ impl<const LIMBS: usize> Iterator for SpigotLittle<LIMBS> {
}
}

struct OwnedVecIterator {
vec: Vec<u64>,
}

impl Iterator for OwnedVecIterator {
type Item = u64;

fn next(&mut self) -> Option<Self::Item> {
self.vec.pop()
}
}

#[cfg(test)]
#[allow(clippy::unreadable_literal)]
#[allow(clippy::zero_prefixed_literal)]
Expand Down
9 changes: 7 additions & 2 deletions src/bit_arr.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::{ParseError, Uint};
use alloc::{borrow::Cow, vec::Vec};
use core::{
ops::{
BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Index, Not, Shl, ShlAssign,
Expand All @@ -8,6 +7,9 @@ use core::{
str::FromStr,
};

#[cfg(feature = "alloc")]
use alloc::{borrow::Cow, vec::Vec};

/// A newtype wrapper around [`Uint`] that restricts operations to those
/// relevant for bit arrays.
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Hash)]
Expand Down Expand Up @@ -206,11 +208,14 @@ impl<const BITS: usize, const LIMBS: usize> Bits<BITS, LIMBS> {
forward! {
fn reverse_bits(self) -> Self;
}
#[cfg(feature = "alloc")]
forward! {
fn as_le_bytes(&self) -> Cow<'_, [u8]>;
fn to_be_bytes_vec(&self) -> Vec<u8>;
}
forward! {
fn to_le_bytes<const BYTES: usize>(&self) -> [u8; BYTES];
fn to_be_bytes<const BYTES: usize>(&self) -> [u8; BYTES];
fn to_be_bytes_vec(&self) -> Vec<u8>;
fn leading_zeros(&self) -> usize;
fn leading_ones(&self) -> usize;
fn trailing_zeros(&self) -> usize;
Expand Down
2 changes: 0 additions & 2 deletions src/bits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,6 @@ impl<const BITS: usize, const LIMBS: usize> Uint<BITS, LIMBS> {
}
}

#[allow(clippy::doc_markdown)]
/// Left shift by `rhs` bits with overflow detection.
///
/// Returns $\mod{\mathtt{value} ⋅ 2^{\mathtt{rhs}}}_{2^{\mathtt{BITS}}}$.
Expand Down Expand Up @@ -301,7 +300,6 @@ impl<const BITS: usize, const LIMBS: usize> Uint<BITS, LIMBS> {
(self, overflow)
}

#[allow(clippy::doc_markdown)]
/// Left shift by `rhs` bits.
///
/// Returns $\mod{\mathtt{value} ⋅ 2^{\mathtt{rhs}}}_{2^{\mathtt{BITS}}}$.
Expand Down
Loading

0 comments on commit 6d4dfd9

Please sign in to comment.