Skip to content

Commit

Permalink
Specialize to_str_common for floats/integers in strconv
Browse files Browse the repository at this point in the history
This allows the integral paths to avoid allocations on the heap

Closes #4424, #4423
  • Loading branch information
alexcrichton committed Jun 30, 2013
1 parent 8fe6fc1 commit d3155fa
Show file tree
Hide file tree
Showing 10 changed files with 250 additions and 197 deletions.
16 changes: 11 additions & 5 deletions src/libextra/terminfo/parm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
//! Parameterized string expansion

use std::{char, vec, util};
use std::num::strconv::{SignNone,SignNeg,SignAll,DigAll,to_str_bytes_common};
use std::num::strconv::{SignNone,SignNeg,SignAll,int_to_str_bytes_common};
use std::iterator::IteratorUtil;

#[deriving(Eq)]
Expand Down Expand Up @@ -469,14 +469,20 @@ priv fn format(val: Param, op: FormatOp, flags: Flags) -> Result<~[u8],~str> {
FormatHex|FormatHEX => 16,
FormatString => util::unreachable()
};
let (s,_) = match op {
let mut s = ~[];
match op {
FormatDigit => {
let sign = if flags.sign { SignAll } else { SignNeg };
to_str_bytes_common(&d, radix, false, sign, DigAll)
do int_to_str_bytes_common(d, radix, sign) |c| {
s.push(c);
}
}
_ => {
do int_to_str_bytes_common(d as uint, radix, SignNone) |c| {
s.push(c);
}
}
_ => to_str_bytes_common(&(d as uint), radix, false, SignNone, DigAll)
};
let mut s = s;
if flags.precision > s.len() {
let mut s_ = vec::with_capacity(flags.precision);
let n = flags.precision - s.len();
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/char.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@

//! Utilities for manipulating the char type

use container::Container;
use option::{None, Option, Some};
use int;
use str::StrSlice;
use unicode::{derived_property, general_category};

Expand Down
22 changes: 11 additions & 11 deletions src/libstd/num/f32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -754,8 +754,8 @@ impl Float for f32 {
///
#[inline]
pub fn to_str(num: f32) -> ~str {
let (r, _) = strconv::to_str_common(
&num, 10u, true, strconv::SignNeg, strconv::DigAll);
let (r, _) = strconv::float_to_str_common(
num, 10u, true, strconv::SignNeg, strconv::DigAll);
r
}

Expand All @@ -768,8 +768,8 @@ pub fn to_str(num: f32) -> ~str {
///
#[inline]
pub fn to_str_hex(num: f32) -> ~str {
let (r, _) = strconv::to_str_common(
&num, 16u, true, strconv::SignNeg, strconv::DigAll);
let (r, _) = strconv::float_to_str_common(
num, 16u, true, strconv::SignNeg, strconv::DigAll);
r
}

Expand All @@ -789,8 +789,8 @@ pub fn to_str_hex(num: f32) -> ~str {
///
#[inline]
pub fn to_str_radix(num: f32, rdx: uint) -> ~str {
let (r, special) = strconv::to_str_common(
&num, rdx, true, strconv::SignNeg, strconv::DigAll);
let (r, special) = strconv::float_to_str_common(
num, rdx, true, strconv::SignNeg, strconv::DigAll);
if special { fail!("number has a special value, \
try to_str_radix_special() if those are expected") }
r
Expand All @@ -807,7 +807,7 @@ pub fn to_str_radix(num: f32, rdx: uint) -> ~str {
///
#[inline]
pub fn to_str_radix_special(num: f32, rdx: uint) -> (~str, bool) {
strconv::to_str_common(&num, rdx, true,
strconv::float_to_str_common(num, rdx, true,
strconv::SignNeg, strconv::DigAll)
}

Expand All @@ -822,8 +822,8 @@ pub fn to_str_radix_special(num: f32, rdx: uint) -> (~str, bool) {
///
#[inline]
pub fn to_str_exact(num: f32, dig: uint) -> ~str {
let (r, _) = strconv::to_str_common(
&num, 10u, true, strconv::SignNeg, strconv::DigExact(dig));
let (r, _) = strconv::float_to_str_common(
num, 10u, true, strconv::SignNeg, strconv::DigExact(dig));
r
}

Expand All @@ -838,8 +838,8 @@ pub fn to_str_exact(num: f32, dig: uint) -> ~str {
///
#[inline]
pub fn to_str_digits(num: f32, dig: uint) -> ~str {
let (r, _) = strconv::to_str_common(
&num, 10u, true, strconv::SignNeg, strconv::DigMax(dig));
let (r, _) = strconv::float_to_str_common(
num, 10u, true, strconv::SignNeg, strconv::DigMax(dig));
r
}

Expand Down
22 changes: 11 additions & 11 deletions src/libstd/num/f64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -796,8 +796,8 @@ impl Float for f64 {
///
#[inline]
pub fn to_str(num: f64) -> ~str {
let (r, _) = strconv::to_str_common(
&num, 10u, true, strconv::SignNeg, strconv::DigAll);
let (r, _) = strconv::float_to_str_common(
num, 10u, true, strconv::SignNeg, strconv::DigAll);
r
}

Expand All @@ -810,8 +810,8 @@ pub fn to_str(num: f64) -> ~str {
///
#[inline]
pub fn to_str_hex(num: f64) -> ~str {
let (r, _) = strconv::to_str_common(
&num, 16u, true, strconv::SignNeg, strconv::DigAll);
let (r, _) = strconv::float_to_str_common(
num, 16u, true, strconv::SignNeg, strconv::DigAll);
r
}

Expand All @@ -831,8 +831,8 @@ pub fn to_str_hex(num: f64) -> ~str {
///
#[inline]
pub fn to_str_radix(num: f64, rdx: uint) -> ~str {
let (r, special) = strconv::to_str_common(
&num, rdx, true, strconv::SignNeg, strconv::DigAll);
let (r, special) = strconv::float_to_str_common(
num, rdx, true, strconv::SignNeg, strconv::DigAll);
if special { fail!("number has a special value, \
try to_str_radix_special() if those are expected") }
r
Expand All @@ -849,7 +849,7 @@ pub fn to_str_radix(num: f64, rdx: uint) -> ~str {
///
#[inline]
pub fn to_str_radix_special(num: f64, rdx: uint) -> (~str, bool) {
strconv::to_str_common(&num, rdx, true,
strconv::float_to_str_common(num, rdx, true,
strconv::SignNeg, strconv::DigAll)
}

Expand All @@ -864,8 +864,8 @@ pub fn to_str_radix_special(num: f64, rdx: uint) -> (~str, bool) {
///
#[inline]
pub fn to_str_exact(num: f64, dig: uint) -> ~str {
let (r, _) = strconv::to_str_common(
&num, 10u, true, strconv::SignNeg, strconv::DigExact(dig));
let (r, _) = strconv::float_to_str_common(
num, 10u, true, strconv::SignNeg, strconv::DigExact(dig));
r
}

Expand All @@ -880,8 +880,8 @@ pub fn to_str_exact(num: f64, dig: uint) -> ~str {
///
#[inline]
pub fn to_str_digits(num: f64, dig: uint) -> ~str {
let (r, _) = strconv::to_str_common(
&num, 10u, true, strconv::SignNeg, strconv::DigMax(dig));
let (r, _) = strconv::float_to_str_common(
num, 10u, true, strconv::SignNeg, strconv::DigMax(dig));
r
}

Expand Down
22 changes: 11 additions & 11 deletions src/libstd/num/float.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ pub mod consts {
///
#[inline]
pub fn to_str(num: float) -> ~str {
let (r, _) = strconv::to_str_common(
&num, 10u, true, strconv::SignNeg, strconv::DigAll);
let (r, _) = strconv::float_to_str_common(
num, 10u, true, strconv::SignNeg, strconv::DigAll);
r
}

Expand All @@ -115,8 +115,8 @@ pub fn to_str(num: float) -> ~str {
///
#[inline]
pub fn to_str_hex(num: float) -> ~str {
let (r, _) = strconv::to_str_common(
&num, 16u, true, strconv::SignNeg, strconv::DigAll);
let (r, _) = strconv::float_to_str_common(
num, 16u, true, strconv::SignNeg, strconv::DigAll);
r
}

Expand All @@ -136,8 +136,8 @@ pub fn to_str_hex(num: float) -> ~str {
///
#[inline]
pub fn to_str_radix(num: float, radix: uint) -> ~str {
let (r, special) = strconv::to_str_common(
&num, radix, true, strconv::SignNeg, strconv::DigAll);
let (r, special) = strconv::float_to_str_common(
num, radix, true, strconv::SignNeg, strconv::DigAll);
if special { fail!("number has a special value, \
try to_str_radix_special() if those are expected") }
r
Expand All @@ -154,7 +154,7 @@ pub fn to_str_radix(num: float, radix: uint) -> ~str {
///
#[inline]
pub fn to_str_radix_special(num: float, radix: uint) -> (~str, bool) {
strconv::to_str_common(&num, radix, true,
strconv::float_to_str_common(num, radix, true,
strconv::SignNeg, strconv::DigAll)
}

Expand All @@ -169,8 +169,8 @@ pub fn to_str_radix_special(num: float, radix: uint) -> (~str, bool) {
///
#[inline]
pub fn to_str_exact(num: float, digits: uint) -> ~str {
let (r, _) = strconv::to_str_common(
&num, 10u, true, strconv::SignNeg, strconv::DigExact(digits));
let (r, _) = strconv::float_to_str_common(
num, 10u, true, strconv::SignNeg, strconv::DigExact(digits));
r
}

Expand All @@ -185,8 +185,8 @@ pub fn to_str_exact(num: float, digits: uint) -> ~str {
///
#[inline]
pub fn to_str_digits(num: float, digits: uint) -> ~str {
let (r, _) = strconv::to_str_common(
&num, 10u, true, strconv::SignNeg, strconv::DigMax(digits));
let (r, _) = strconv::float_to_str_common(
num, 10u, true, strconv::SignNeg, strconv::DigMax(digits));
r
}

Expand Down
27 changes: 18 additions & 9 deletions src/libstd/num/int_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ macro_rules! int_module (($T:ty, $bits:expr) => (mod generated {
use num::{ToStrRadix, FromStrRadix};
use num::{Zero, One, strconv};
use prelude::*;
use str;

pub use cmp::{min, max};

Expand Down Expand Up @@ -529,25 +530,33 @@ impl FromStrRadix for $T {
/// Convert to a string as a byte slice in a given base.
#[inline]
pub fn to_str_bytes<U>(n: $T, radix: uint, f: &fn(v: &[u8]) -> U) -> U {
let (buf, _) = strconv::to_str_bytes_common(&n, radix, false,
strconv::SignNeg, strconv::DigAll);
f(buf)
// The radix can be as low as 2, so we need at least 64 characters for a
// base 2 number, and then we need another for a possible '-' character.
let mut buf = [0u8, ..65];
let mut cur = 0;
do strconv::int_to_str_bytes_common(n, radix, strconv::SignNeg) |i| {
buf[cur] = i;
cur += 1;
}
f(buf.slice(0, cur))
}

/// Convert to a string in base 10.
#[inline]
pub fn to_str(num: $T) -> ~str {
let (buf, _) = strconv::to_str_common(&num, 10u, false,
strconv::SignNeg, strconv::DigAll);
buf
to_str_radix(num, 10u)
}

/// Convert to a string in a given base.
#[inline]
pub fn to_str_radix(num: $T, radix: uint) -> ~str {
let (buf, _) = strconv::to_str_common(&num, radix, false,
strconv::SignNeg, strconv::DigAll);
buf
let mut buf: ~[u8] = ~[];
do strconv::int_to_str_bytes_common(num, radix, strconv::SignNeg) |i| {
buf.push(i);
}
// We know we generated valid utf-8, so we don't need to go through that
// check.
unsafe { str::raw::from_bytes_owned(buf) }
}

impl ToStr for $T {
Expand Down
Loading

5 comments on commit d3155fa

@bors
Copy link
Contributor

@bors bors commented on d3155fa Jun 30, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from cmr
at alexcrichton@d3155fa

@bors
Copy link
Contributor

@bors bors commented on d3155fa Jun 30, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging alexcrichton/rust/issue-4432 = d3155fa into auto

@bors
Copy link
Contributor

@bors bors commented on d3155fa Jun 30, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alexcrichton/rust/issue-4432 = d3155fa merged ok, testing candidate = 1790400

@bors
Copy link
Contributor

@bors bors commented on d3155fa Jun 30, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding master to auto = 1790400

Please sign in to comment.