]> git.lizzy.rs Git - rust.git/blob - src/libcore/fmt/float.rs
core: fix deprecated warnings
[rust.git] / src / libcore / fmt / float.rs
1 // Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use fmt::{Formatter, Result, LowerExp, UpperExp, Display, Debug};
12 use mem::MaybeUninit;
13 use num::flt2dec;
14
15 // Don't inline this so callers don't use the stack space this function
16 // requires unless they have to.
17 #[inline(never)]
18 fn float_to_decimal_common_exact<T>(fmt: &mut Formatter, num: &T,
19                                     sign: flt2dec::Sign, precision: usize) -> Result
20     where T: flt2dec::DecodableFloat
21 {
22     unsafe {
23         let mut buf = MaybeUninit::<[u8; 1024]>::uninitialized(); // enough for f32 and f64
24         let mut parts = MaybeUninit::<[flt2dec::Part; 4]>::uninitialized();
25         let formatted = flt2dec::to_exact_fixed_str(flt2dec::strategy::grisu::format_exact,
26                                                     *num, sign, precision,
27                                                     false, buf.get_mut(), parts.get_mut());
28         fmt.pad_formatted_parts(&formatted)
29     }
30 }
31
32 // Don't inline this so callers that call both this and the above won't wind
33 // up using the combined stack space of both functions in some cases.
34 #[inline(never)]
35 fn float_to_decimal_common_shortest<T>(fmt: &mut Formatter, num: &T,
36                                        sign: flt2dec::Sign, precision: usize) -> Result
37     where T: flt2dec::DecodableFloat
38 {
39     unsafe {
40         // enough for f32 and f64
41         let mut buf = MaybeUninit::<[u8; flt2dec::MAX_SIG_DIGITS]>::uninitialized();
42         let mut parts = MaybeUninit::<[flt2dec::Part; 4]>::uninitialized();
43         let formatted = flt2dec::to_shortest_str(flt2dec::strategy::grisu::format_shortest, *num,
44                                                  sign, precision, false, buf.get_mut(),
45                                                  parts.get_mut());
46         fmt.pad_formatted_parts(&formatted)
47     }
48 }
49
50 // Common code of floating point Debug and Display.
51 fn float_to_decimal_common<T>(fmt: &mut Formatter, num: &T,
52                               negative_zero: bool, min_precision: usize) -> Result
53     where T: flt2dec::DecodableFloat
54 {
55     let force_sign = fmt.sign_plus();
56     let sign = match (force_sign, negative_zero) {
57         (false, false) => flt2dec::Sign::Minus,
58         (false, true)  => flt2dec::Sign::MinusRaw,
59         (true,  false) => flt2dec::Sign::MinusPlus,
60         (true,  true)  => flt2dec::Sign::MinusPlusRaw,
61     };
62
63     if let Some(precision) = fmt.precision {
64         float_to_decimal_common_exact(fmt, num, sign, precision)
65     } else {
66         float_to_decimal_common_shortest(fmt, num, sign, min_precision)
67     }
68 }
69
70 // Don't inline this so callers don't use the stack space this function
71 // requires unless they have to.
72 #[inline(never)]
73 fn float_to_exponential_common_exact<T>(fmt: &mut Formatter, num: &T,
74                                         sign: flt2dec::Sign, precision: usize,
75                                         upper: bool) -> Result
76     where T: flt2dec::DecodableFloat
77 {
78     unsafe {
79         let mut buf = MaybeUninit::<[u8; 1024]>::uninitialized(); // enough for f32 and f64
80         let mut parts = MaybeUninit::<[flt2dec::Part; 6]>::uninitialized();
81         let formatted = flt2dec::to_exact_exp_str(flt2dec::strategy::grisu::format_exact,
82                                                   *num, sign, precision,
83                                                   upper, buf.get_mut(), parts.get_mut());
84         fmt.pad_formatted_parts(&formatted)
85     }
86 }
87
88 // Don't inline this so callers that call both this and the above won't wind
89 // up using the combined stack space of both functions in some cases.
90 #[inline(never)]
91 fn float_to_exponential_common_shortest<T>(fmt: &mut Formatter,
92                                            num: &T, sign: flt2dec::Sign,
93                                            upper: bool) -> Result
94     where T: flt2dec::DecodableFloat
95 {
96     unsafe {
97         // enough for f32 and f64
98         let mut buf = MaybeUninit::<[u8; flt2dec::MAX_SIG_DIGITS]>::uninitialized();
99         let mut parts = MaybeUninit::<[flt2dec::Part; 6]>::uninitialized();
100         let formatted = flt2dec::to_shortest_exp_str(flt2dec::strategy::grisu::format_shortest,
101                                                      *num, sign, (0, 0), upper,
102                                                      buf.get_mut(), parts.get_mut());
103         fmt.pad_formatted_parts(&formatted)
104     }
105 }
106
107 // Common code of floating point LowerExp and UpperExp.
108 fn float_to_exponential_common<T>(fmt: &mut Formatter, num: &T, upper: bool) -> Result
109     where T: flt2dec::DecodableFloat
110 {
111     let force_sign = fmt.sign_plus();
112     let sign = match force_sign {
113         false => flt2dec::Sign::Minus,
114         true  => flt2dec::Sign::MinusPlus,
115     };
116
117     if let Some(precision) = fmt.precision {
118         // 1 integral digit + `precision` fractional digits = `precision + 1` total digits
119         float_to_exponential_common_exact(fmt, num, sign, precision + 1, upper)
120     } else {
121         float_to_exponential_common_shortest(fmt, num, sign, upper)
122     }
123 }
124
125 macro_rules! floating {
126     ($ty:ident) => (
127         #[stable(feature = "rust1", since = "1.0.0")]
128         impl Debug for $ty {
129             fn fmt(&self, fmt: &mut Formatter) -> Result {
130                 float_to_decimal_common(fmt, self, true, 1)
131             }
132         }
133
134         #[stable(feature = "rust1", since = "1.0.0")]
135         impl Display for $ty {
136             fn fmt(&self, fmt: &mut Formatter) -> Result {
137                 float_to_decimal_common(fmt, self, false, 0)
138             }
139         }
140
141         #[stable(feature = "rust1", since = "1.0.0")]
142         impl LowerExp for $ty {
143             fn fmt(&self, fmt: &mut Formatter) -> Result {
144                 float_to_exponential_common(fmt, self, false)
145             }
146         }
147
148         #[stable(feature = "rust1", since = "1.0.0")]
149         impl UpperExp for $ty {
150             fn fmt(&self, fmt: &mut Formatter) -> Result {
151                 float_to_exponential_common(fmt, self, true)
152             }
153         }
154     )
155 }
156
157 floating! { f32 }
158 floating! { f64 }