Skip to content

Commit

Permalink
Merge pull request #19 from paritytech/no-std
Browse files Browse the repository at this point in the history
Add no_std support
  • Loading branch information
NikVolf authored Aug 14, 2017
2 parents 58fa622 + 04205c8 commit eda04b8
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 34 deletions.
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ matrix:
allow_failures:
- rust: nightly
script:
- cargo build --features "heapsizeof"
- cargo test --features "heapsizeof"
- cargo build --features=heapsizeof,std
- cargo test --features=heapsizeof,std
11 changes: 8 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,14 @@ build = "build.rs"
rustc_version = "0.2"

[dependencies]
rustc-hex = "1.0"
byteorder = "1.0"
rustc-hex = { version = "1.0", optional = true }
heapsize = { version = "0.4", optional = true }
byteorder = { version = "1", default-features = false }

[features]
heapsizeof = ["heapsize"]
heapsizeof = ["heapsize", "std"]
std = ["rustc-hex"]

[[example]]
name = "modular"
required-features = ["std"]
9 changes: 8 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,19 @@
#![cfg_attr(asm_available, feature(asm))]

#![cfg_attr(not(feature="std"), no_std)]

extern crate byteorder;

#[cfg(feature="std")]
extern crate rustc_hex;

#[cfg(feature="heapsizeof")]
#[macro_use]
#[macro_use]
extern crate heapsize;

#[cfg(feature="std")]
extern crate core;

pub mod uint;
pub use ::uint::*;
68 changes: 40 additions & 28 deletions src/uint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@
//! implementations for even more speed, hidden behind the `x64_arithmetic`
//! feature flag.
use std::{fmt, cmp, str};
use std::ops::{Shr, Shl, BitAnd, BitOr, BitXor, Not, Div, Rem, Mul, Add, Sub};
use std::cmp::Ordering;
use core::str;
use core::ops::{Shr, Shl, BitAnd, BitOr, BitXor, Not, Div, Rem, Mul, Add, Sub};

use byteorder::{ByteOrder, BigEndian, LittleEndian};
use rustc_hex::{ToHex, FromHex, FromHexError};
//use rustc_hex::{ToHex, FromHex, FromHexError};

/// Conversion from decimal string error
#[derive(Debug, PartialEq)]
Expand Down Expand Up @@ -84,7 +84,7 @@ macro_rules! uint_overflowing_add_reg {
#[cfg(all(asm_available, target_arch="x86_64"))]
macro_rules! uint_overflowing_add {
(U256, $n_words: expr, $self_expr: expr, $other: expr) => ({
let mut result: [u64; $n_words] = unsafe { ::std::mem::uninitialized() };
let mut result: [u64; $n_words] = unsafe { ::core::mem::uninitialized() };
let self_t: &[u64; $n_words] = &$self_expr.0;
let other_t: &[u64; $n_words] = &$other.0;

Expand All @@ -107,7 +107,7 @@ macro_rules! uint_overflowing_add {
(U256(result), overflow != 0)
});
(U512, $n_words: expr, $self_expr: expr, $other: expr) => ({
let mut result: [u64; $n_words] = unsafe { ::std::mem::uninitialized() };
let mut result: [u64; $n_words] = unsafe { ::core::mem::uninitialized() };
let self_t: &[u64; $n_words] = &$self_expr.0;
let other_t: &[u64; $n_words] = &$other.0;

Expand Down Expand Up @@ -188,7 +188,7 @@ macro_rules! uint_overflowing_sub_reg {
#[cfg(all(asm_available, target_arch="x86_64"))]
macro_rules! uint_overflowing_sub {
(U256, $n_words: expr, $self_expr: expr, $other: expr) => ({
let mut result: [u64; $n_words] = unsafe { ::std::mem::uninitialized() };
let mut result: [u64; $n_words] = unsafe { ::core::mem::uninitialized() };
let self_t: &[u64; $n_words] = &$self_expr.0;
let other_t: &[u64; $n_words] = &$other.0;

Expand All @@ -210,7 +210,7 @@ macro_rules! uint_overflowing_sub {
(U256(result), overflow != 0)
});
(U512, $n_words: expr, $self_expr: expr, $other: expr) => ({
let mut result: [u64; $n_words] = unsafe { ::std::mem::uninitialized() };
let mut result: [u64; $n_words] = unsafe { ::core::mem::uninitialized() };
let self_t: &[u64; $n_words] = &$self_expr.0;
let other_t: &[u64; $n_words] = &$other.0;

Expand Down Expand Up @@ -262,7 +262,7 @@ macro_rules! uint_overflowing_sub {
#[cfg(all(asm_available, target_arch="x86_64"))]
macro_rules! uint_overflowing_mul {
(U256, $n_words: expr, $self_expr: expr, $other: expr) => ({
let mut result: [u64; $n_words] = unsafe { ::std::mem::uninitialized() };
let mut result: [u64; $n_words] = unsafe { ::core::mem::uninitialized() };
let self_t: &[u64; $n_words] = &$self_expr.0;
let other_t: &[u64; $n_words] = &$other.0;

Expand Down Expand Up @@ -612,8 +612,12 @@ macro_rules! construct_uint {
}

/// Convert to hex string.
#[cfg(feature="std")]
#[inline]
pub fn to_hex(&self) -> String {
use core::cmp;
use rustc_hex::ToHex;;

if self.is_zero() { return "0".to_owned(); } // special case.
let mut bytes = [0u8; 8 * $n_words];
self.to_big_endian(&mut bytes);
Expand Down Expand Up @@ -758,7 +762,7 @@ macro_rules! construct_uint {
}
}

/// Division with overflow
/// Division with overflow
pub fn overflowing_div(self, other: $name) -> ($name, bool) {
(self / other, false)
}
Expand Down Expand Up @@ -849,10 +853,13 @@ macro_rules! construct_uint {
}
}

#[cfg(feature="std")]
impl str::FromStr for $name {
type Err = FromHexError;
type Err = ::rustc_hex::FromHexError;

fn from_str(value: &str) -> Result<$name, Self::Err> {
use rustc_hex::FromHex;

let bytes: Vec<u8> = match value.len() % 2 == 0 {
true => try!(value.from_hex()),
false => try!(("0".to_owned() + value).from_hex())
Expand Down Expand Up @@ -1047,33 +1054,35 @@ macro_rules! construct_uint {
}

impl Ord for $name {
fn cmp(&self, other: &$name) -> Ordering {
fn cmp(&self, other: &$name) -> ::core::cmp::Ordering {
let &$name(ref me) = self;
let &$name(ref you) = other;
let mut i = $n_words;
while i > 0 {
i -= 1;
if me[i] < you[i] { return Ordering::Less; }
if me[i] > you[i] { return Ordering::Greater; }
if me[i] < you[i] { return ::core::cmp::Ordering::Less; }
if me[i] > you[i] { return ::core::cmp::Ordering::Greater; }
}
Ordering::Equal
::core::cmp::Ordering::Equal
}
}

impl PartialOrd for $name {
fn partial_cmp(&self, other: &$name) -> Option<Ordering> {
fn partial_cmp(&self, other: &$name) -> Option<::core::cmp::Ordering> {
Some(self.cmp(other))
}
}

impl fmt::Debug for $name {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(self, f)
#[cfg(feature="std")]
impl ::core::fmt::Debug for $name {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Display::fmt(self, f)
}
}

impl fmt::Display for $name {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
#[cfg(feature="std")]
impl ::core::fmt::Display for $name {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
if self.is_zero() {
return write!(f, "0");
}
Expand All @@ -1091,8 +1100,9 @@ macro_rules! construct_uint {
}
}

impl fmt::LowerHex for $name {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
#[cfg(feature="std")]
impl ::core::fmt::LowerHex for $name {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
let &$name(ref data) = self;
try!(write!(f, "0x"));
let mut latch = false;
Expand All @@ -1109,6 +1119,7 @@ macro_rules! construct_uint {
}
}

#[cfg(feature="std")]
impl From<&'static str> for $name {
fn from(s: &'static str) -> Self {
s.parse().unwrap()
Expand All @@ -1128,7 +1139,7 @@ impl U256 {
pub fn full_mul(self, other: U256) -> U512 {
let self_t: &[u64; 4] = &self.0;
let other_t: &[u64; 4] = &other.0;
let mut result: [u64; 8] = unsafe { ::std::mem::uninitialized() };
let mut result: [u64; 8] = unsafe { ::core::mem::uninitialized() };
unsafe {
asm!("
mov $8, %rax
Expand Down Expand Up @@ -1422,6 +1433,7 @@ impl From<U256> for u32 {
known_heap_size!(0, U128, U256);

#[cfg(test)]
#[cfg(feature="std")]
mod tests {
use uint::{U128, U256, U512};
use std::str::FromStr;
Expand Down Expand Up @@ -1452,7 +1464,7 @@ mod tests {
assert_eq!(U256([0x12f0, 0 , 0, 0]), U256::from(&[0, 0, 0, 0, 0, 0, 0, 0x12u8, 0xf0][..]));
assert_eq!(U256([0x12f0, 1 , 0, 0]), U256::from(&[1, 0, 0, 0, 0, 0, 0, 0x12u8, 0xf0][..]));
assert_eq!(
U256([0x12f0, 1 , 0x0910203040506077, 0x8090a0b0c0d0e0f0]),
U256([0x12f0, 1 , 0x0910203040506077, 0x8090a0b0c0d0e0f0]),
U256::from(&
[
0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0,
Expand All @@ -1463,7 +1475,7 @@ mod tests {
)
);
assert_eq!(
U256([0x00192437100019fa, 0x243710, 0, 0]),
U256([0x00192437100019fa, 0x243710, 0, 0]),
U256::from(&[0x24u8, 0x37, 0x10,0, 0x19, 0x24, 0x37, 0x10, 0, 0x19, 0xfa][..])
);

Expand All @@ -1476,7 +1488,7 @@ mod tests {
assert_eq!(U256([0x12f0, 0 , 0, 0]), U256::from_str("0000000012f0").unwrap());
assert_eq!(U256([0x12f0, 1 , 0, 0]), U256::from_str("0100000000000012f0").unwrap());
assert_eq!(
U256([0x12f0, 1 , 0x0910203040506077, 0x8090a0b0c0d0e0f0]),
U256([0x12f0, 1 , 0x0910203040506077, 0x8090a0b0c0d0e0f0]),
U256::from_str("8090a0b0c0d0e0f00910203040506077000000000000000100000000000012f0").unwrap()
);
}
Expand Down Expand Up @@ -1903,7 +1915,7 @@ mod tests {
let (_, overflow) = U256([0, 0, 2, 1]).overflowing_sub(U256([0, 0, 3, 1]));
assert!(overflow);

let (result, overflow) =
let (result, overflow) =
U256([::std::u64::MAX, ::std::u64::MAX, ::std::u64::MAX, ::std::u64::MAX])
.overflowing_sub(U256([::std::u64::MAX/2, ::std::u64::MAX/2, ::std::u64::MAX/2, ::std::u64::MAX/2]));

Expand Down

0 comments on commit eda04b8

Please sign in to comment.