Skip to content

Commit

Permalink
approach 2: &mut [MaybeUninit<T>]
Browse files Browse the repository at this point in the history
More ergonomic than approach 1: you can use the `set` method instead of
`ptr::write`.

Constructing an array of `MaybeUninit` is terribly unergonomic. You can't write
`[MaybeUninit::uninitialized(); N]`; you have to write
`[MaybeUninit::uninitialized(), MaybeUninit::uninitialized(), ..]` N times.
  • Loading branch information
japaric committed Sep 1, 2018
1 parent 2327942 commit f82f7f0
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 23 deletions.
10 changes: 8 additions & 2 deletions src/libcore/fmt/float.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,16 @@ fn float_to_decimal_common_exact<T>(fmt: &mut Formatter, num: &T,
{
unsafe {
let mut buf = MaybeUninit::<[u8; 1024]>::uninitialized(); // enough for f32 and f64
let mut parts = MaybeUninit::<[flt2dec::Part; 4]>::uninitialized();
// let mut parts = [MaybeUninit::uninitialized(); 4];
let mut parts = [
MaybeUninit::uninitialized(),
MaybeUninit::uninitialized(),
MaybeUninit::uninitialized(),
MaybeUninit::uninitialized(),
];
let formatted = flt2dec::to_exact_fixed_str(flt2dec::strategy::grisu::format_exact,
*num, sign, precision,
false, buf.get_mut(), parts.get_mut());
false, buf.get_mut(), &mut parts);
fmt.pad_formatted_parts(&formatted)
}
}
Expand Down
51 changes: 30 additions & 21 deletions src/libcore/num/flt2dec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ functions.
issue = "0")]

use i16;
use mem::MaybeUninit;
use slice;
pub use self::decoder::{decode, DecodableFloat, FullDecoded, Decoded};

pub mod estimator;
Expand Down Expand Up @@ -604,32 +606,35 @@ pub fn to_exact_exp_str<'a, T, F>(mut format_exact: F, v: T,
/// `[+][0.][0000][2][0000]` with `frac_digits = 10`.
pub fn to_exact_fixed_str<'a, T, F>(mut format_exact: F, v: T,
sign: Sign, frac_digits: usize, _upper: bool,
buf: &'a mut [u8], parts: &'a mut [Part<'a>]) -> Formatted<'a>
buf: &'a mut [u8],
parts: &'a mut [MaybeUninit<Part<'a>>]) -> Formatted<'a>
where T: DecodableFloat, F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) {
assert!(parts.len() >= 4);

let (negative, full_decoded) = decode(v);
let sign = determine_sign(sign, &full_decoded, negative);
let parts_head = parts.as_mut_ptr() as *mut Part;
let parts_len = parts.len();
match full_decoded {
FullDecoded::Nan => {
parts[0] = Part::Copy(b"NaN");
Formatted { sign, parts: &parts[..1] }
FullDecoded::Nan => unsafe {
parts[0].set(Part::Copy(b"NaN"));
Formatted { sign, parts: slice::from_raw_parts(parts_head, 1) }
}
FullDecoded::Infinite => {
parts[0] = Part::Copy(b"inf");
Formatted { sign, parts: &parts[..1] }
FullDecoded::Infinite => unsafe {
parts[0].set(Part::Copy(b"inf"));
Formatted { sign, parts: slice::from_raw_parts(parts_head, 1) }
}
FullDecoded::Zero => {
FullDecoded::Zero => unsafe {
if frac_digits > 0 { // [0.][0000]
parts[0] = Part::Copy(b"0.");
parts[1] = Part::Zero(frac_digits);
Formatted { sign, parts: &parts[..2] }
parts[0].set(Part::Copy(b"0."));
parts[1].set(Part::Zero(frac_digits));
Formatted { sign, parts: slice::from_raw_parts(parts_head, 2) }
} else {
parts[0] = Part::Copy(b"0");
Formatted { sign, parts: &parts[..1] }
parts[0].set(Part::Copy(b"0"));
Formatted { sign, parts: slice::from_raw_parts(parts_head, 1) }
}
}
FullDecoded::Finite(ref decoded) => {
FullDecoded::Finite(ref decoded) => unsafe {
let maxlen = estimate_max_buf_len(decoded.exp);
assert!(buf.len() >= maxlen);

Expand All @@ -644,18 +649,22 @@ pub fn to_exact_fixed_str<'a, T, F>(mut format_exact: F, v: T,
// only after the final rounding-up; it's a regular case with `exp = limit + 1`.
debug_assert_eq!(len, 0);
if frac_digits > 0 { // [0.][0000]
parts[0] = Part::Copy(b"0.");
parts[1] = Part::Zero(frac_digits);
Formatted { sign, parts: &parts[..2] }
parts[0].set(Part::Copy(b"0."));
parts[1].set(Part::Zero(frac_digits));
Formatted { sign, parts: slice::from_raw_parts(parts_head, 2) }
} else {
parts[0] = Part::Copy(b"0");
Formatted { sign, parts: &parts[..1] }
parts[0].set(Part::Copy(b"0"));
Formatted { sign, parts: slice::from_raw_parts(parts_head, 1) }
}
} else {
Formatted { sign,
parts: digits_to_dec_str(&buf[..len], exp, frac_digits, parts) }
parts: digits_to_dec_str(
&buf[..len],
exp,
frac_digits,
slice::from_raw_parts_mut(parts_head, parts_len),
) }
}
}
}
}

0 comments on commit f82f7f0

Please sign in to comment.