Skip to content

Commit 7947edb

Browse files
committed
approach 1: &mut MaybeUninit<[T; N]>
having that type as an argument to a function is not flexible because you need to pick a value for N -- limiting the size of the buffer that can be passed. &mut MaybeUninit<[T]> would be more flexible but it doesn't exist. &mut MaybeUninit<[T; N]> will become more flexible once we have const generics.
1 parent 2327942 commit 7947edb

File tree

2 files changed

+25
-24
lines changed

2 files changed

+25
-24
lines changed

src/libcore/fmt/float.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ fn float_to_decimal_common_exact<T>(fmt: &mut Formatter, num: &T,
2424
let mut parts = MaybeUninit::<[flt2dec::Part; 4]>::uninitialized();
2525
let formatted = flt2dec::to_exact_fixed_str(flt2dec::strategy::grisu::format_exact,
2626
*num, sign, precision,
27-
false, buf.get_mut(), parts.get_mut());
27+
false, buf.get_mut(), &mut parts);
2828
fmt.pad_formatted_parts(&formatted)
2929
}
3030
}

src/libcore/num/flt2dec/mod.rs

Lines changed: 24 additions & 23 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 {ptr, slice};
134136
pub use self::decoder::{decode, DecodableFloat, FullDecoded, Decoded};
135137

136138
pub mod estimator;
@@ -604,32 +606,32 @@ 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>; 4]>) -> Formatted<'a>
608611
where T: DecodableFloat, F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) {
609-
assert!(parts.len() >= 4);
610-
611612
let (negative, full_decoded) = decode(v);
612613
let sign = determine_sign(sign, &full_decoded, negative);
614+
let parts_head = parts.as_mut_ptr() as *mut Part;
613615
match full_decoded {
614-
FullDecoded::Nan => {
615-
parts[0] = Part::Copy(b"NaN");
616-
Formatted { sign, parts: &parts[..1] }
616+
FullDecoded::Nan => unsafe {
617+
ptr::write(parts_head, Part::Copy(b"NaN"));
618+
Formatted { sign, parts: slice::from_raw_parts(parts_head, 1) }
617619
}
618-
FullDecoded::Infinite => {
619-
parts[0] = Part::Copy(b"inf");
620-
Formatted { sign, parts: &parts[..1] }
620+
FullDecoded::Infinite => unsafe {
621+
ptr::write(parts_head, Part::Copy(b"inf"));
622+
Formatted { sign, parts: slice::from_raw_parts(parts_head, 1) }
621623
}
622-
FullDecoded::Zero => {
624+
FullDecoded::Zero => unsafe {
623625
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] }
626+
ptr::write(parts_head, Part::Copy(b"0."));
627+
ptr::write(parts_head.offset(1), Part::Zero(frac_digits));
628+
Formatted { sign, parts: slice::from_raw_parts(parts_head, 2) }
627629
} else {
628-
parts[0] = Part::Copy(b"0");
629-
Formatted { sign, parts: &parts[..1] }
630+
ptr::write(parts_head, Part::Copy(b"0"));
631+
Formatted { sign, parts: slice::from_raw_parts(parts_head, 1) }
630632
}
631633
}
632-
FullDecoded::Finite(ref decoded) => {
634+
FullDecoded::Finite(ref decoded) => unsafe {
633635
let maxlen = estimate_max_buf_len(decoded.exp);
634636
assert!(buf.len() >= maxlen);
635637

@@ -644,18 +646,17 @@ pub fn to_exact_fixed_str<'a, T, F>(mut format_exact: F, v: T,
644646
// only after the final rounding-up; it's a regular case with `exp = limit + 1`.
645647
debug_assert_eq!(len, 0);
646648
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] }
649+
ptr::write(parts_head, Part::Copy(b"0."));
650+
ptr::write(parts_head.offset(1), Part::Zero(frac_digits));
651+
Formatted { sign, parts: slice::from_raw_parts(parts_head, 2) }
650652
} else {
651-
parts[0] = Part::Copy(b"0");
652-
Formatted { sign, parts: &parts[..1] }
653+
ptr::write(parts_head, Part::Copy(b"0"));
654+
Formatted { sign, parts: slice::from_raw_parts(parts_head, 2) }
653655
}
654656
} else {
655657
Formatted { sign,
656-
parts: digits_to_dec_str(&buf[..len], exp, frac_digits, parts) }
658+
parts: digits_to_dec_str(&buf[..len], exp, frac_digits, parts.get_mut()) }
657659
}
658660
}
659661
}
660662
}
661-

0 commit comments

Comments
 (0)