Skip to content

Commit d3155fa

Browse files
committed
Specialize to_str_common for floats/integers in strconv
This allows the integral paths to avoid allocations on the heap Closes #4424, #4423
1 parent 8fe6fc1 commit d3155fa

File tree

10 files changed

+250
-197
lines changed

10 files changed

+250
-197
lines changed

src/libextra/terminfo/parm.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
//! Parameterized string expansion
1212
1313
use std::{char, vec, util};
14-
use std::num::strconv::{SignNone,SignNeg,SignAll,DigAll,to_str_bytes_common};
14+
use std::num::strconv::{SignNone,SignNeg,SignAll,int_to_str_bytes_common};
1515
use std::iterator::IteratorUtil;
1616

1717
#[deriving(Eq)]
@@ -469,14 +469,20 @@ priv fn format(val: Param, op: FormatOp, flags: Flags) -> Result<~[u8],~str> {
469469
FormatHex|FormatHEX => 16,
470470
FormatString => util::unreachable()
471471
};
472-
let (s,_) = match op {
472+
let mut s = ~[];
473+
match op {
473474
FormatDigit => {
474475
let sign = if flags.sign { SignAll } else { SignNeg };
475-
to_str_bytes_common(&d, radix, false, sign, DigAll)
476+
do int_to_str_bytes_common(d, radix, sign) |c| {
477+
s.push(c);
478+
}
479+
}
480+
_ => {
481+
do int_to_str_bytes_common(d as uint, radix, SignNone) |c| {
482+
s.push(c);
483+
}
476484
}
477-
_ => to_str_bytes_common(&(d as uint), radix, false, SignNone, DigAll)
478485
};
479-
let mut s = s;
480486
if flags.precision > s.len() {
481487
let mut s_ = vec::with_capacity(flags.precision);
482488
let n = flags.precision - s.len();

src/libstd/char.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010

1111
//! Utilities for manipulating the char type
1212
13-
use container::Container;
1413
use option::{None, Option, Some};
14+
use int;
1515
use str::StrSlice;
1616
use unicode::{derived_property, general_category};
1717

src/libstd/num/f32.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -754,8 +754,8 @@ impl Float for f32 {
754754
///
755755
#[inline]
756756
pub fn to_str(num: f32) -> ~str {
757-
let (r, _) = strconv::to_str_common(
758-
&num, 10u, true, strconv::SignNeg, strconv::DigAll);
757+
let (r, _) = strconv::float_to_str_common(
758+
num, 10u, true, strconv::SignNeg, strconv::DigAll);
759759
r
760760
}
761761

@@ -768,8 +768,8 @@ pub fn to_str(num: f32) -> ~str {
768768
///
769769
#[inline]
770770
pub fn to_str_hex(num: f32) -> ~str {
771-
let (r, _) = strconv::to_str_common(
772-
&num, 16u, true, strconv::SignNeg, strconv::DigAll);
771+
let (r, _) = strconv::float_to_str_common(
772+
num, 16u, true, strconv::SignNeg, strconv::DigAll);
773773
r
774774
}
775775

@@ -789,8 +789,8 @@ pub fn to_str_hex(num: f32) -> ~str {
789789
///
790790
#[inline]
791791
pub fn to_str_radix(num: f32, rdx: uint) -> ~str {
792-
let (r, special) = strconv::to_str_common(
793-
&num, rdx, true, strconv::SignNeg, strconv::DigAll);
792+
let (r, special) = strconv::float_to_str_common(
793+
num, rdx, true, strconv::SignNeg, strconv::DigAll);
794794
if special { fail!("number has a special value, \
795795
try to_str_radix_special() if those are expected") }
796796
r
@@ -807,7 +807,7 @@ pub fn to_str_radix(num: f32, rdx: uint) -> ~str {
807807
///
808808
#[inline]
809809
pub fn to_str_radix_special(num: f32, rdx: uint) -> (~str, bool) {
810-
strconv::to_str_common(&num, rdx, true,
810+
strconv::float_to_str_common(num, rdx, true,
811811
strconv::SignNeg, strconv::DigAll)
812812
}
813813

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

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

src/libstd/num/f64.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -796,8 +796,8 @@ impl Float for f64 {
796796
///
797797
#[inline]
798798
pub fn to_str(num: f64) -> ~str {
799-
let (r, _) = strconv::to_str_common(
800-
&num, 10u, true, strconv::SignNeg, strconv::DigAll);
799+
let (r, _) = strconv::float_to_str_common(
800+
num, 10u, true, strconv::SignNeg, strconv::DigAll);
801801
r
802802
}
803803

@@ -810,8 +810,8 @@ pub fn to_str(num: f64) -> ~str {
810810
///
811811
#[inline]
812812
pub fn to_str_hex(num: f64) -> ~str {
813-
let (r, _) = strconv::to_str_common(
814-
&num, 16u, true, strconv::SignNeg, strconv::DigAll);
813+
let (r, _) = strconv::float_to_str_common(
814+
num, 16u, true, strconv::SignNeg, strconv::DigAll);
815815
r
816816
}
817817

@@ -831,8 +831,8 @@ pub fn to_str_hex(num: f64) -> ~str {
831831
///
832832
#[inline]
833833
pub fn to_str_radix(num: f64, rdx: uint) -> ~str {
834-
let (r, special) = strconv::to_str_common(
835-
&num, rdx, true, strconv::SignNeg, strconv::DigAll);
834+
let (r, special) = strconv::float_to_str_common(
835+
num, rdx, true, strconv::SignNeg, strconv::DigAll);
836836
if special { fail!("number has a special value, \
837837
try to_str_radix_special() if those are expected") }
838838
r
@@ -849,7 +849,7 @@ pub fn to_str_radix(num: f64, rdx: uint) -> ~str {
849849
///
850850
#[inline]
851851
pub fn to_str_radix_special(num: f64, rdx: uint) -> (~str, bool) {
852-
strconv::to_str_common(&num, rdx, true,
852+
strconv::float_to_str_common(num, rdx, true,
853853
strconv::SignNeg, strconv::DigAll)
854854
}
855855

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

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

src/libstd/num/float.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,8 @@ pub mod consts {
101101
///
102102
#[inline]
103103
pub fn to_str(num: float) -> ~str {
104-
let (r, _) = strconv::to_str_common(
105-
&num, 10u, true, strconv::SignNeg, strconv::DigAll);
104+
let (r, _) = strconv::float_to_str_common(
105+
num, 10u, true, strconv::SignNeg, strconv::DigAll);
106106
r
107107
}
108108

@@ -115,8 +115,8 @@ pub fn to_str(num: float) -> ~str {
115115
///
116116
#[inline]
117117
pub fn to_str_hex(num: float) -> ~str {
118-
let (r, _) = strconv::to_str_common(
119-
&num, 16u, true, strconv::SignNeg, strconv::DigAll);
118+
let (r, _) = strconv::float_to_str_common(
119+
num, 16u, true, strconv::SignNeg, strconv::DigAll);
120120
r
121121
}
122122

@@ -136,8 +136,8 @@ pub fn to_str_hex(num: float) -> ~str {
136136
///
137137
#[inline]
138138
pub fn to_str_radix(num: float, radix: uint) -> ~str {
139-
let (r, special) = strconv::to_str_common(
140-
&num, radix, true, strconv::SignNeg, strconv::DigAll);
139+
let (r, special) = strconv::float_to_str_common(
140+
num, radix, true, strconv::SignNeg, strconv::DigAll);
141141
if special { fail!("number has a special value, \
142142
try to_str_radix_special() if those are expected") }
143143
r
@@ -154,7 +154,7 @@ pub fn to_str_radix(num: float, radix: uint) -> ~str {
154154
///
155155
#[inline]
156156
pub fn to_str_radix_special(num: float, radix: uint) -> (~str, bool) {
157-
strconv::to_str_common(&num, radix, true,
157+
strconv::float_to_str_common(num, radix, true,
158158
strconv::SignNeg, strconv::DigAll)
159159
}
160160

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

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

src/libstd/num/int_macros.rs

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ macro_rules! int_module (($T:ty, $bits:expr) => (mod generated {
1717
use num::{ToStrRadix, FromStrRadix};
1818
use num::{Zero, One, strconv};
1919
use prelude::*;
20+
use str;
2021

2122
pub use cmp::{min, max};
2223

@@ -529,25 +530,33 @@ impl FromStrRadix for $T {
529530
/// Convert to a string as a byte slice in a given base.
530531
#[inline]
531532
pub fn to_str_bytes<U>(n: $T, radix: uint, f: &fn(v: &[u8]) -> U) -> U {
532-
let (buf, _) = strconv::to_str_bytes_common(&n, radix, false,
533-
strconv::SignNeg, strconv::DigAll);
534-
f(buf)
533+
// The radix can be as low as 2, so we need at least 64 characters for a
534+
// base 2 number, and then we need another for a possible '-' character.
535+
let mut buf = [0u8, ..65];
536+
let mut cur = 0;
537+
do strconv::int_to_str_bytes_common(n, radix, strconv::SignNeg) |i| {
538+
buf[cur] = i;
539+
cur += 1;
540+
}
541+
f(buf.slice(0, cur))
535542
}
536543
537544
/// Convert to a string in base 10.
538545
#[inline]
539546
pub fn to_str(num: $T) -> ~str {
540-
let (buf, _) = strconv::to_str_common(&num, 10u, false,
541-
strconv::SignNeg, strconv::DigAll);
542-
buf
547+
to_str_radix(num, 10u)
543548
}
544549
545550
/// Convert to a string in a given base.
546551
#[inline]
547552
pub fn to_str_radix(num: $T, radix: uint) -> ~str {
548-
let (buf, _) = strconv::to_str_common(&num, radix, false,
549-
strconv::SignNeg, strconv::DigAll);
550-
buf
553+
let mut buf: ~[u8] = ~[];
554+
do strconv::int_to_str_bytes_common(num, radix, strconv::SignNeg) |i| {
555+
buf.push(i);
556+
}
557+
// We know we generated valid utf-8, so we don't need to go through that
558+
// check.
559+
unsafe { str::raw::from_bytes_owned(buf) }
551560
}
552561
553562
impl ToStr for $T {

0 commit comments

Comments
 (0)