@@ -17,13 +17,11 @@ use char::Char;
17
17
use clone:: Clone ;
18
18
use from_str:: from_str;
19
19
use iter:: Iterator ;
20
- use num:: { NumCast , Zero , One , cast, Int , Bounded } ;
21
- use num:: { Float , FPNaN , FPInfinite , ToPrimitive } ;
22
20
use num;
23
- use ops:: { Add , Sub , Mul , Div , Rem , Neg } ;
21
+ use num:: { Zero , One , cast, Int , Bounded } ;
22
+ use num:: { Float , FPNaN , FPInfinite , ToPrimitive } ;
24
23
use option:: { None , Option , Some } ;
25
24
use slice:: { ImmutableSlice , MutableSlice , CloneableVector } ;
26
- use std:: cmp:: { PartialOrd , PartialEq } ;
27
25
use str:: { Str , StrSlice } ;
28
26
use string:: String ;
29
27
use vec:: Vec ;
@@ -70,51 +68,6 @@ pub enum SignFormat {
70
68
SignAll ,
71
69
}
72
70
73
- /// Encompasses functions used by the string converter.
74
- pub trait NumStrConv {
75
- /// Returns the NaN value.
76
- fn nan ( ) -> Option < Self > ;
77
-
78
- /// Returns the infinite value.
79
- fn inf ( ) -> Option < Self > ;
80
-
81
- /// Returns the negative infinite value.
82
- fn neg_inf ( ) -> Option < Self > ;
83
-
84
- /// Returns -0.0.
85
- fn neg_zero ( ) -> Option < Self > ;
86
-
87
- /// Rounds the number toward zero.
88
- fn round_to_zero ( & self ) -> Self ;
89
-
90
- /// Returns the fractional part of the number.
91
- fn fractional_part ( & self ) -> Self ;
92
- }
93
-
94
- macro_rules! impl_NumStrConv_Floating ( ( $t: ty) => (
95
- impl NumStrConv for $t {
96
- #[ inline]
97
- fn nan( ) -> Option <$t> { Some ( 0.0 / 0.0 ) }
98
- #[ inline]
99
- fn inf( ) -> Option <$t> { Some ( 1.0 / 0.0 ) }
100
- #[ inline]
101
- fn neg_inf( ) -> Option <$t> { Some ( -1.0 / 0.0 ) }
102
- #[ inline]
103
- fn neg_zero( ) -> Option <$t> { Some ( -0.0 ) }
104
-
105
- #[ inline]
106
- fn round_to_zero( & self ) -> $t { self . trunc( ) }
107
- #[ inline]
108
- fn fractional_part( & self ) -> $t { self . fract( ) }
109
- }
110
- ) )
111
-
112
- // FIXME: #4955
113
- // Replace by two generic impls for traits 'Integral' and 'Floating'
114
- impl_NumStrConv_Floating ! ( f32 )
115
- impl_NumStrConv_Floating ! ( f64 )
116
-
117
-
118
71
// Special value strings as [u8] consts.
119
72
static INF_BUF : [ u8 , ..3 ] = [ b'i' , b'n' , b'f' ] ;
120
73
static POS_INF_BUF : [ u8 , ..4 ] = [ b'+' , b'i' , b'n' , b'f' ] ;
@@ -234,8 +187,7 @@ fn int_to_str_bytes_common<T: Int>(num: T, radix: uint, sign: SignFormat, f: |u8
234
187
* - Fails if `radix` > 25 and `exp_format` is `ExpBin` due to conflict
235
188
* between digit and exponent sign `'p'`.
236
189
*/
237
- pub fn float_to_str_bytes_common < T : NumCast +Zero +One +PartialEq +PartialOrd +Float +
238
- Div < T , T > +Neg < T > +Rem < T , T > +Mul < T , T > > (
190
+ pub fn float_to_str_bytes_common < T : Float > (
239
191
num : T , radix : uint , negative_zero : bool ,
240
192
sign : SignFormat , digits : SignificantDigits , exp_format : ExponentFormat , exp_upper : bool
241
193
) -> ( Vec < u8 > , bool ) {
@@ -467,8 +419,7 @@ pub fn float_to_str_bytes_common<T:NumCast+Zero+One+PartialEq+PartialOrd+Float+
467
419
* `to_str_bytes_common()`, for details see there.
468
420
*/
469
421
#[ inline]
470
- pub fn float_to_str_common < T : NumCast +Zero +One +PartialEq +PartialOrd +NumStrConv +Float +
471
- Div < T , T > +Neg < T > +Rem < T , T > +Mul < T , T > > (
422
+ pub fn float_to_str_common < T : Float > (
472
423
num : T , radix : uint , negative_zero : bool ,
473
424
sign : SignFormat , digits : SignificantDigits , exp_format : ExponentFormat , exp_capital : bool
474
425
) -> ( String , bool ) {
@@ -484,15 +435,13 @@ static DIGIT_I_RADIX: uint = ('i' as uint) - ('a' as uint) + 11u;
484
435
static DIGIT_E_RADIX : uint = ( 'e' as uint ) - ( 'a' as uint ) + 11 u;
485
436
486
437
/**
487
- * Parses a byte slice as a number. This is meant to
438
+ * Parses a string as a number. This is meant to
488
439
* be a common base implementation for all numeric string conversion
489
440
* functions like `from_str()` or `from_str_radix()`.
490
441
*
491
442
* # Arguments
492
- * - `buf ` - The byte slice to parse.
443
+ * - `src ` - The string to parse.
493
444
* - `radix` - Which base to parse the number as. Accepts 2-36.
494
- * - `negative` - Whether to accept negative numbers.
495
- * - `fractional` - Whether to accept numbers with fractional parts.
496
445
* - `special` - Whether to accept special values like `inf`
497
446
* and `NaN`. Can conflict with `radix`, see Failure.
498
447
* - `exponent` - Which exponent format to accept. Options are:
@@ -504,7 +453,6 @@ static DIGIT_E_RADIX: uint = ('e' as uint) - ('a' as uint) + 11u;
504
453
* - `ExpBin`: Accepts numbers with a binary exponent like `42P-8` or
505
454
* `FFp128`. The exponent string itself is always base 10.
506
455
* Can conflict with `radix`, see Failure.
507
- * - `empty_zero` - Whether to accept an empty `buf` as a 0 or not.
508
456
*
509
457
* # Return value
510
458
* Returns `Some(n)` if `buf` parses to a number n without overflowing, and
@@ -520,11 +468,8 @@ static DIGIT_E_RADIX: uint = ('e' as uint) - ('a' as uint) + 11u;
520
468
* - Fails if `radix` > 18 and `special == true` due to conflict
521
469
* between digit and lowest first character in `inf` and `NaN`, the `'i'`.
522
470
*/
523
- pub fn from_str_bytes_common < T : NumCast +Zero +One +PartialEq +PartialOrd +Div < T , T > +
524
- Mul < T , T > +Sub < T , T > +Neg < T > +Add < T , T > +
525
- NumStrConv +Clone > (
526
- buf : & [ u8 ] , radix : uint , negative : bool , fractional : bool ,
527
- special : bool , exponent : ExponentFormat , empty_zero : bool ,
471
+ pub fn from_str_float < T : Float > (
472
+ src : & str , radix : uint , special : bool , exponent : ExponentFormat ,
528
473
) -> Option < T > {
529
474
match exponent {
530
475
ExpDec if radix >= DIGIT_E_RADIX // decimal exponent 'e'
@@ -548,33 +493,25 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+PartialEq+PartialOrd+Div<T,T>+
548
493
let _0: T = Zero :: zero ( ) ;
549
494
let _1: T = One :: one ( ) ;
550
495
let radix_gen: T = cast ( radix as int ) . unwrap ( ) ;
496
+ let buf = src. as_bytes ( ) ;
551
497
552
498
let len = buf. len ( ) ;
553
499
554
500
if len == 0 {
555
- if empty_zero {
556
- return Some ( _0) ;
557
- } else {
558
- return None ;
559
- }
501
+ return None ;
560
502
}
561
503
562
504
if special {
563
505
if buf == INF_BUF || buf == POS_INF_BUF {
564
- return NumStrConv :: inf ( ) ;
506
+ return Some ( Float :: infinity ( ) ) ;
565
507
} else if buf == NEG_INF_BUF {
566
- if negative {
567
- return NumStrConv :: neg_inf ( ) ;
568
- } else {
569
- return None ;
570
- }
508
+ return Some ( Float :: neg_infinity ( ) ) ;
571
509
} else if buf == NAN_BUF {
572
- return NumStrConv :: nan ( ) ;
510
+ return Some ( Float :: nan ( ) ) ;
573
511
}
574
512
}
575
513
576
514
let ( start, accum_positive) = match buf[ 0 ] as char {
577
- '-' if !negative => return None ,
578
515
'-' => ( 1 u, false ) ,
579
516
'+' => ( 1 u, true ) ,
580
517
_ => ( 0 u, true )
@@ -606,17 +543,17 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+PartialEq+PartialOrd+Div<T,T>+
606
543
// Detect overflow by comparing to last value, except
607
544
// if we've not seen any non-zero digits.
608
545
if last_accum != _0 {
609
- if accum_positive && accum <= last_accum { return NumStrConv :: inf ( ) ; }
610
- if !accum_positive && accum >= last_accum { return NumStrConv :: neg_inf ( ) ; }
546
+ if accum_positive && accum <= last_accum { return Some ( Float :: infinity ( ) ) ; }
547
+ if !accum_positive && accum >= last_accum { return Some ( Float :: neg_infinity ( ) ) ; }
611
548
612
549
// Detect overflow by reversing the shift-and-add process
613
550
if accum_positive &&
614
551
( last_accum != ( ( accum - cast ( digit as int ) . unwrap ( ) ) /radix_gen. clone ( ) ) ) {
615
- return NumStrConv :: inf ( ) ;
552
+ return Some ( Float :: infinity ( ) ) ;
616
553
}
617
554
if !accum_positive &&
618
555
( last_accum != ( ( accum + cast ( digit as int ) . unwrap ( ) ) /radix_gen. clone ( ) ) ) {
619
- return NumStrConv :: neg_inf ( ) ;
556
+ return Some ( Float :: neg_infinity ( ) ) ;
620
557
}
621
558
}
622
559
last_accum = accum. clone ( ) ;
@@ -626,7 +563,7 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+PartialEq+PartialOrd+Div<T,T>+
626
563
exp_found = true ;
627
564
break ; // start of exponent
628
565
}
629
- '.' if fractional => {
566
+ '.' => {
630
567
i += 1 u; // skip the '.'
631
568
break ; // start of fractional part
632
569
}
@@ -660,8 +597,8 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+PartialEq+PartialOrd+Div<T,T>+
660
597
}
661
598
662
599
// Detect overflow by comparing to last value
663
- if accum_positive && accum < last_accum { return NumStrConv :: inf ( ) ; }
664
- if !accum_positive && accum > last_accum { return NumStrConv :: neg_inf ( ) ; }
600
+ if accum_positive && accum < last_accum { return Some ( Float :: infinity ( ) ) ; }
601
+ if !accum_positive && accum > last_accum { return Some ( Float :: neg_infinity ( ) ) ; }
665
602
last_accum = accum. clone ( ) ;
666
603
}
667
604
None => match c {
@@ -680,11 +617,7 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+PartialEq+PartialOrd+Div<T,T>+
680
617
// Special case: buf not empty, but does not contain any digit in front
681
618
// of the exponent sign -> number is empty string
682
619
if i == start {
683
- if empty_zero {
684
- return Some ( _0) ;
685
- } else {
686
- return None ;
687
- }
620
+ return None ;
688
621
}
689
622
690
623
let mut multiplier = _1. clone ( ) ;
@@ -717,20 +650,6 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+PartialEq+PartialOrd+Div<T,T>+
717
650
Some ( accum * multiplier)
718
651
}
719
652
720
- /**
721
- * Parses a string as a number. This is a wrapper for
722
- * `from_str_bytes_common()`, for details see there.
723
- */
724
- #[ inline]
725
- pub fn from_str_common < T : NumCast +Zero +One +PartialEq +PartialOrd +Div < T , T > +Mul < T , T > +
726
- Sub < T , T > +Neg < T > +Add < T , T > +NumStrConv +Clone > (
727
- buf : & str , radix : uint , negative : bool , fractional : bool ,
728
- special : bool , exponent : ExponentFormat , empty_zero : bool ,
729
- ) -> Option < T > {
730
- from_str_bytes_common ( buf. as_bytes ( ) , radix, negative,
731
- fractional, special, exponent, empty_zero)
732
- }
733
-
734
653
pub fn from_str_radix_int < T : Int > ( src : & str , radix : uint ) -> Option < T > {
735
654
fn cast < T : Int > ( x : uint ) -> T {
736
655
num:: cast ( x) . unwrap ( )
@@ -791,20 +710,19 @@ pub fn from_str_radix_int<T: Int>(src: &str, radix: uint) -> Option<T> {
791
710
mod test {
792
711
use super :: * ;
793
712
use option:: * ;
713
+ use num:: Float ;
794
714
795
715
#[ test]
796
716
fn from_str_issue7588 ( ) {
797
717
let u : Option < u8 > = from_str_radix_int ( "1000" , 10 ) ;
798
718
assert_eq ! ( u, None ) ;
799
719
let s : Option < i16 > = from_str_radix_int ( "80000" , 10 ) ;
800
720
assert_eq ! ( s, None ) ;
801
- let f : Option < f32 > = from_str_common (
802
- "10000000000000000000000000000000000000000" , 10 , false , false , false ,
803
- ExpNone , false ) ;
804
- assert_eq ! ( f, NumStrConv :: inf( ) )
805
- let fe : Option < f32 > = from_str_common ( "1e40" , 10 , false , false , false ,
806
- ExpDec , false ) ;
807
- assert_eq ! ( fe, NumStrConv :: inf( ) )
721
+ let f : Option < f32 > = from_str_float (
722
+ "10000000000000000000000000000000000000000" , 10 , false , ExpNone ) ;
723
+ assert_eq ! ( f, Some ( Float :: infinity( ) ) )
724
+ let fe : Option < f32 > = from_str_float ( "1e40" , 10 , false , ExpDec ) ;
725
+ assert_eq ! ( fe, Some ( Float :: infinity( ) ) )
808
726
}
809
727
}
810
728
0 commit comments