Skip to content

Commit f82f7f0

Browse files
committed
approach 2: &mut [MaybeUninit<T>]
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.
1 parent 2327942 commit f82f7f0

File tree

2 files changed

+38
-23
lines changed

2 files changed

+38
-23
lines changed

src/libcore/fmt/float.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,16 @@ fn float_to_decimal_common_exact<T>(fmt: &mut Formatter, num: &T,
2121
{
2222
unsafe {
2323
let mut buf = MaybeUninit::<[u8; 1024]>::uninitialized(); // enough for f32 and f64
24-
let mut parts = MaybeUninit::<[flt2dec::Part; 4]>::uninitialized();
24+
// let mut parts = [MaybeUninit::uninitialized(); 4];
25+
let mut parts = [
26+
MaybeUninit::uninitialized(),
27+
MaybeUninit::uninitialized(),
28+
MaybeUninit::uninitialized(),
29+
MaybeUninit::uninitialized(),
30+
];
2531
let formatted = flt2dec::to_exact_fixed_str(flt2dec::strategy::grisu::format_exact,
2632
*num, sign, precision,
27-
false, buf.get_mut(), parts.get_mut());
33+
false, buf.get_mut(), &mut parts);
2834
fmt.pad_formatted_parts(&formatted)
2935
}
3036
}

src/libcore/num/flt2dec/mod.rs

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ functions.
131131
issue = "0")]
132132

133133
use i16;
134+
use mem::MaybeUninit;
135+
use slice;
134136
pub use self::decoder::{decode, DecodableFloat, FullDecoded, Decoded};
135137

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

611614
let (negative, full_decoded) = decode(v);
612615
let sign = determine_sign(sign, &full_decoded, negative);
616+
let parts_head = parts.as_mut_ptr() as *mut Part;
617+
let parts_len = parts.len();
613618
match full_decoded {
614-
FullDecoded::Nan => {
615-
parts[0] = Part::Copy(b"NaN");
616-
Formatted { sign, parts: &parts[..1] }
619+
FullDecoded::Nan => unsafe {
620+
parts[0].set(Part::Copy(b"NaN"));
621+
Formatted { sign, parts: slice::from_raw_parts(parts_head, 1) }
617622
}
618-
FullDecoded::Infinite => {
619-
parts[0] = Part::Copy(b"inf");
620-
Formatted { sign, parts: &parts[..1] }
623+
FullDecoded::Infinite => unsafe {
624+
parts[0].set(Part::Copy(b"inf"));
625+
Formatted { sign, parts: slice::from_raw_parts(parts_head, 1) }
621626
}
622-
FullDecoded::Zero => {
627+
FullDecoded::Zero => unsafe {
623628
if frac_digits > 0 { // [0.][0000]
624-
parts[0] = Part::Copy(b"0.");
625-
parts[1] = Part::Zero(frac_digits);
626-
Formatted { sign, parts: &parts[..2] }
629+
parts[0].set(Part::Copy(b"0."));
630+
parts[1].set(Part::Zero(frac_digits));
631+
Formatted { sign, parts: slice::from_raw_parts(parts_head, 2) }
627632
} else {
628-
parts[0] = Part::Copy(b"0");
629-
Formatted { sign, parts: &parts[..1] }
633+
parts[0].set(Part::Copy(b"0"));
634+
Formatted { sign, parts: slice::from_raw_parts(parts_head, 1) }
630635
}
631636
}
632-
FullDecoded::Finite(ref decoded) => {
637+
FullDecoded::Finite(ref decoded) => unsafe {
633638
let maxlen = estimate_max_buf_len(decoded.exp);
634639
assert!(buf.len() >= maxlen);
635640

@@ -644,18 +649,22 @@ pub fn to_exact_fixed_str<'a, T, F>(mut format_exact: F, v: T,
644649
// only after the final rounding-up; it's a regular case with `exp = limit + 1`.
645650
debug_assert_eq!(len, 0);
646651
if frac_digits > 0 { // [0.][0000]
647-
parts[0] = Part::Copy(b"0.");
648-
parts[1] = Part::Zero(frac_digits);
649-
Formatted { sign, parts: &parts[..2] }
652+
parts[0].set(Part::Copy(b"0."));
653+
parts[1].set(Part::Zero(frac_digits));
654+
Formatted { sign, parts: slice::from_raw_parts(parts_head, 2) }
650655
} else {
651-
parts[0] = Part::Copy(b"0");
652-
Formatted { sign, parts: &parts[..1] }
656+
parts[0].set(Part::Copy(b"0"));
657+
Formatted { sign, parts: slice::from_raw_parts(parts_head, 1) }
653658
}
654659
} else {
655660
Formatted { sign,
656-
parts: digits_to_dec_str(&buf[..len], exp, frac_digits, parts) }
661+
parts: digits_to_dec_str(
662+
&buf[..len],
663+
exp,
664+
frac_digits,
665+
slice::from_raw_parts_mut(parts_head, parts_len),
666+
) }
657667
}
658668
}
659669
}
660670
}
661-

0 commit comments

Comments
 (0)