Skip to content

Re-introduce the std feature #30

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Feb 2, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ categories = [ "algorithms", "science" ]
license = "MIT/Apache-2.0"
repository = "https://github.com/rust-num/num-traits"
name = "num-traits"
version = "0.1.42"
version = "0.2.0-pre"
readme = "README.md"

[dependencies]

[features]
default = ["std"]
std = []
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Add this to your `Cargo.toml`:

```toml
[dependencies]
num-traits = "0.1"
num-traits = "0.2"
```

and this to your crate root:
Expand All @@ -21,6 +21,19 @@ and this to your crate root:
extern crate num_traits;
```

## Features

This crate can be used without the standard library (`#![no_std]`) by disabling
the default `std` feature. Use this in `Cargo.toml`:

```toml
[dependencies.num-traits]
version = "0.2"
default-features = false
```

The `Float` and `Real` traits are only available when `std` is enabled.

## Releases

Release notes are available in [RELEASES.md](RELEASES.md).
Expand Down
6 changes: 4 additions & 2 deletions ci/test_full.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ set -ex

echo Testing num-traits on rustc ${TRAVIS_RUST_VERSION}

# num-integer should build and test everywhere.
# num-traits should build and test everywhere.
cargo build --verbose
cargo test --verbose

# We have no features to test...
# test `no_std`
cargo build --verbose --no-default-features
cargo test --verbose --no-default-features
8 changes: 4 additions & 4 deletions src/bounds.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::{usize, u8, u16, u32, u64};
use std::{isize, i8, i16, i32, i64};
use std::{f32, f64};
use std::num::Wrapping;
use core::{usize, u8, u16, u32, u64};
use core::{isize, i8, i16, i32, i64};
use core::{f32, f64};
use core::num::Wrapping;

/// Numbers which have upper and lower bounds
pub trait Bounded {
Expand Down
15 changes: 9 additions & 6 deletions src/cast.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::mem::size_of;
use std::num::Wrapping;
use core::f64;
use core::mem::size_of;
use core::num::Wrapping;

use identities::Zero;
use bounds::Bounded;
Expand Down Expand Up @@ -226,8 +227,10 @@ macro_rules! impl_to_primitive_float_to_float {
// Make sure the value is in range for the cast.
// NaN and +-inf are cast as they are.
let n = $slf as f64;
let max_value: $DstT = ::std::$DstT::MAX;
if !n.is_finite() || (-max_value as f64 <= n && n <= max_value as f64) {
let max_value: $DstT = ::core::$DstT::MAX;
if n != n || n == f64::INFINITY || n == f64::NEG_INFINITY
|| (-max_value as f64 <= n && n <= max_value as f64)
{
Some($slf as $DstT)
} else {
None
Expand Down Expand Up @@ -522,8 +525,8 @@ impl_as_primitive!(bool => u8, i8, u16, i16, u32, i32, u64, isize, usize, i64);

#[test]
fn to_primitive_float() {
use std::f32;
use std::f64;
use core::f32;
use core::f64;

let f32_toolarge = 1e39f64;
assert_eq!(f32_toolarge.to_f32(), None);
Expand Down
20 changes: 17 additions & 3 deletions src/float.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
#[cfg(feature = "std")]
use std::mem;
#[cfg(feature = "std")]
use std::ops::Neg;
#[cfg(feature = "std")]
use std::num::FpCategory;

// Used for default implementation of `epsilon`
#[cfg(feature = "std")]
use std::f32;

#[cfg(feature = "std")]
use {Num, NumCast};

// FIXME: these doctests aren't actually helpful, because they're using and
// testing the inherent methods directly, not going through `Float`.

/// Generic trait for floating point numbers
///
/// This trait is only available with the `std` feature.
#[cfg(feature = "std")]
pub trait Float
: Num
+ Copy
Expand Down Expand Up @@ -923,6 +932,7 @@ pub trait Float
fn integer_decode(self) -> (u64, i16, i8);
}

#[cfg(feature = "std")]
macro_rules! float_impl {
($T:ident $decode:ident) => (
impl Float for $T {
Expand Down Expand Up @@ -1219,6 +1229,7 @@ macro_rules! float_impl {
)
}

#[cfg(feature = "std")]
fn integer_decode_f32(f: f32) -> (u64, i16, i8) {
let bits: u32 = unsafe { mem::transmute(f) };
let sign: i8 = if bits >> 31 == 0 {
Expand All @@ -1237,6 +1248,7 @@ fn integer_decode_f32(f: f32) -> (u64, i16, i8) {
(mantissa as u64, exponent, sign)
}

#[cfg(feature = "std")]
fn integer_decode_f64(f: f64) -> (u64, i16, i8) {
let bits: u64 = unsafe { mem::transmute(f) };
let sign: i8 = if bits >> 63 == 0 {
Expand All @@ -1255,7 +1267,9 @@ fn integer_decode_f64(f: f64) -> (u64, i16, i8) {
(mantissa, exponent, sign)
}

#[cfg(feature = "std")]
float_impl!(f32 integer_decode_f32);
#[cfg(feature = "std")]
float_impl!(f64 integer_decode_f64);

macro_rules! float_const_impl {
Expand All @@ -1272,7 +1286,7 @@ macro_rules! float_const_impl {
$(
#[inline]
fn $constant() -> Self {
::std::$T::consts::$constant
::core::$T::consts::$constant
}
)+
}
Expand Down Expand Up @@ -1314,13 +1328,13 @@ float_const_impl! {
SQRT_2,
}

#[cfg(test)]
#[cfg(all(test, feature = "std"))]
mod tests {
use Float;

#[test]
fn convert_deg_rad() {
use std::f64::consts;
use core::f64::consts;

const DEG_RAD_PAIRS: [(f64, f64); 7] = [
(0.0, 0.),
Expand Down
4 changes: 2 additions & 2 deletions src/identities.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::ops::{Add, Mul};
use std::num::Wrapping;
use core::ops::{Add, Mul};
use core::num::Wrapping;

/// Defines an additive identity element for `Self`.
pub trait Zero: Sized + Add<Self, Output = Self> {
Expand Down
2 changes: 1 addition & 1 deletion src/int.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr};
use core::ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr};

use {Num, NumCast};
use bounds::Bounded;
Expand Down
63 changes: 39 additions & 24 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,30 @@

//! Numeric traits for generic mathematics

#![doc(html_root_url = "https://docs.rs/num-traits/0.1")]
#![doc(html_root_url = "https://docs.rs/num-traits/0.2")]

use std::ops::{Add, Sub, Mul, Div, Rem};
use std::ops::{AddAssign, SubAssign, MulAssign, DivAssign, RemAssign};
use std::num::Wrapping;
use std::fmt;
#![deny(unconditional_recursion)]

#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(feature = "std")]
extern crate core;

use core::ops::{Add, Sub, Mul, Div, Rem};
use core::ops::{AddAssign, SubAssign, MulAssign, DivAssign, RemAssign};
use core::num::Wrapping;
use core::fmt;

pub use bounds::Bounded;
pub use float::{Float, FloatConst};
#[cfg(feature = "std")]
pub use float::Float;
pub use float::FloatConst;
// pub use real::Real; // NOTE: Don't do this, it breaks `use num_traits::*;`.
pub use identities::{Zero, One, zero, one};
pub use ops::checked::*;
pub use ops::wrapping::*;
pub use ops::checked::{CheckedAdd, CheckedSub, CheckedMul, CheckedDiv, CheckedShl, CheckedShr};
pub use ops::wrapping::{WrappingAdd, WrappingMul, WrappingSub};
pub use ops::saturating::Saturating;
pub use sign::{Signed, Unsigned, abs, abs_sub, signum};
pub use cast::*;
pub use cast::{AsPrimitive, FromPrimitive, ToPrimitive, NumCast, cast};
pub use int::PrimInt;
pub use pow::{pow, checked_pow};

Expand All @@ -34,6 +42,7 @@ pub mod sign;
pub mod ops;
pub mod bounds;
pub mod float;
#[cfg(feature = "std")]
pub mod real;
pub mod cast;
pub mod int;
Expand Down Expand Up @@ -130,10 +139,10 @@ impl<T> NumAssignRef for T where T: NumAssign + for<'r> NumAssignOps<&'r T> {}
macro_rules! int_trait_impl {
($name:ident for $($t:ty)*) => ($(
impl $name for $t {
type FromStrRadixErr = ::std::num::ParseIntError;
type FromStrRadixErr = ::core::num::ParseIntError;
#[inline]
fn from_str_radix(s: &str, radix: u32)
-> Result<Self, ::std::num::ParseIntError>
-> Result<Self, ::core::num::ParseIntError>
{
<$t>::from_str_radix(s, radix)
}
Expand All @@ -159,7 +168,7 @@ pub enum FloatErrorKind {
Empty,
Invalid,
}
// FIXME: std::num::ParseFloatError is stable in 1.0, but opaque to us,
// FIXME: core::num::ParseFloatError is stable in 1.0, but opaque to us,
// so there's not really any way for us to reuse it.
#[derive(Debug)]
pub struct ParseFloatError {
Expand All @@ -181,7 +190,7 @@ impl fmt::Display for ParseFloatError {
// with this implementation ourselves until we want to make a breaking change.
// (would have to drop it from `Num` though)
macro_rules! float_trait_impl {
($name:ident for $($t:ty)*) => ($(
($name:ident for $($t:ident)*) => ($(
impl $name for $t {
type FromStrRadixErr = ParseFloatError;

Expand All @@ -193,9 +202,9 @@ macro_rules! float_trait_impl {

// Special values
match src {
"inf" => return Ok(Float::infinity()),
"-inf" => return Ok(Float::neg_infinity()),
"NaN" => return Ok(Float::nan()),
"inf" => return Ok(core::$t::INFINITY),
"-inf" => return Ok(core::$t::NEG_INFINITY),
"NaN" => return Ok(core::$t::NAN),
_ => {},
}

Expand Down Expand Up @@ -236,15 +245,15 @@ macro_rules! float_trait_impl {
// if we've not seen any non-zero digits.
if prev_sig != 0.0 {
if is_positive && sig <= prev_sig
{ return Ok(Float::infinity()); }
{ return Ok(core::$t::INFINITY); }
if !is_positive && sig >= prev_sig
{ return Ok(Float::neg_infinity()); }
{ return Ok(core::$t::NEG_INFINITY); }

// Detect overflow by reversing the shift-and-add process
if is_positive && (prev_sig != (sig - digit as $t) / radix as $t)
{ return Ok(Float::infinity()); }
{ return Ok(core::$t::INFINITY); }
if !is_positive && (prev_sig != (sig + digit as $t) / radix as $t)
{ return Ok(Float::neg_infinity()); }
{ return Ok(core::$t::NEG_INFINITY); }
}
prev_sig = sig;
},
Expand Down Expand Up @@ -280,9 +289,9 @@ macro_rules! float_trait_impl {
};
// Detect overflow by comparing to last value
if is_positive && sig < prev_sig
{ return Ok(Float::infinity()); }
{ return Ok(core::$t::INFINITY); }
if !is_positive && sig > prev_sig
{ return Ok(Float::neg_infinity()); }
{ return Ok(core::$t::NEG_INFINITY); }
prev_sig = sig;
},
None => match c {
Expand Down Expand Up @@ -316,9 +325,15 @@ macro_rules! float_trait_impl {
None => return Err(PFE { kind: Invalid }),
};

#[cfg(feature = "std")]
fn pow(base: $t, exp: usize) -> $t {
Float::powi(base, exp as i32)
}
// otherwise uses the generic `pow` from the root

match (is_positive, exp) {
(true, Ok(exp)) => base.powi(exp as i32),
(false, Ok(exp)) => 1.0 / base.powi(exp as i32),
(true, Ok(exp)) => pow(base, exp),
(false, Ok(exp)) => 1.0 / pow(base, exp),
(_, Err(_)) => return Err(PFE { kind: Invalid }),
}
},
Expand Down
2 changes: 1 addition & 1 deletion src/ops/checked.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::ops::{Add, Sub, Mul, Div, Shl, Shr};
use core::ops::{Add, Sub, Mul, Div, Shl, Shr};

/// Performs addition that returns `None` instead of wrapping around on
/// overflow.
Expand Down
4 changes: 2 additions & 2 deletions src/ops/wrapping.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::ops::{Add, Sub, Mul};
use std::num::Wrapping;
use core::ops::{Add, Sub, Mul};
use core::num::Wrapping;

macro_rules! wrapping_impl {
($trait_name:ident, $method:ident, $t:ty) => {
Expand Down
2 changes: 1 addition & 1 deletion src/pow.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::ops::Mul;
use core::ops::Mul;
use {One, CheckedMul};

/// Raises a value to the power of exp, using exponentiation by squaring.
Expand Down
2 changes: 2 additions & 0 deletions src/real.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ use {Num, NumCast, Float};
///
/// See [this Wikipedia article](https://en.wikipedia.org/wiki/Real_data_type)
/// for a list of data types that could meaningfully implement this trait.
///
/// This trait is only available with the `std` feature.
pub trait Real
: Num
+ Copy
Expand Down
Loading