1818// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1919// KIND, either express or implied.
2020
21+ use core:: ptr;
22+
23+ #[ cfg( maybe_uninit) ]
24+ use core:: mem:: MaybeUninit ;
25+
26+ #[ cfg( not( maybe_uninit) ) ]
2127use core:: mem;
2228
2329use common:: * ;
@@ -48,12 +54,14 @@ fn mul_shift_all(
4854 m : u64 ,
4955 mul : & ( u64 , u64 ) ,
5056 j : u32 ,
51- vp : & mut u64 ,
52- vm : & mut u64 ,
57+ vp : * mut u64 ,
58+ vm : * mut u64 ,
5359 mm_shift : u32 ,
5460) -> u64 {
55- * vp = mul_shift ( 4 * m + 2 , mul, j) ;
56- * vm = mul_shift ( 4 * m - 1 - mm_shift as u64 , mul, j) ;
61+ unsafe {
62+ ptr:: write ( vp, mul_shift ( 4 * m + 2 , mul, j) ) ;
63+ ptr:: write ( vm, mul_shift ( 4 * m - 1 - mm_shift as u64 , mul, j) ) ;
64+ }
5765 mul_shift ( 4 * m, mul, j)
5866}
5967
@@ -177,8 +185,17 @@ pub fn d2d(ieee_mantissa: u64, ieee_exponent: u32) -> FloatingDecimal64 {
177185
178186 // Step 3: Convert to a decimal power base using 128-bit arithmetic.
179187 let mut vr: u64 ;
180- let mut vp: u64 = unsafe { mem:: uninitialized ( ) } ;
181- let mut vm: u64 = unsafe { mem:: uninitialized ( ) } ;
188+ let mut vp: u64 ;
189+ let mut vm: u64 ;
190+ #[ cfg( not( maybe_uninit) ) ]
191+ {
192+ vp = unsafe { mem:: uninitialized ( ) } ;
193+ vm = unsafe { mem:: uninitialized ( ) } ;
194+ }
195+ #[ cfg( maybe_uninit) ]
196+ let mut vp_uninit: MaybeUninit < u64 > = MaybeUninit :: uninit ( ) ;
197+ #[ cfg( maybe_uninit) ]
198+ let mut vm_uninit: MaybeUninit < u64 > = MaybeUninit :: uninit ( ) ;
182199 let e10: i32 ;
183200 let mut vm_is_trailing_zeros = false ;
184201 let mut vr_is_trailing_zeros = false ;
@@ -201,10 +218,21 @@ pub fn d2d(ieee_mantissa: u64, ieee_exponent: u32) -> FloatingDecimal64 {
201218 DOUBLE_POW5_INV_SPLIT . get_unchecked ( q as usize )
202219 } ,
203220 i as u32 ,
204- & mut vp,
205- & mut vm,
221+ #[ cfg( maybe_uninit) ]
222+ { vp_uninit. as_mut_ptr ( ) } ,
223+ #[ cfg( not( maybe_uninit) ) ]
224+ { & mut vp } ,
225+ #[ cfg( maybe_uninit) ]
226+ { vm_uninit. as_mut_ptr ( ) } ,
227+ #[ cfg( not( maybe_uninit) ) ]
228+ { & mut vm } ,
206229 mm_shift,
207230 ) ;
231+ #[ cfg( maybe_uninit) ]
232+ {
233+ vp = unsafe { vp_uninit. assume_init ( ) } ;
234+ vm = unsafe { vm_uninit. assume_init ( ) } ;
235+ }
208236 if q <= 21 {
209237 // This should use q <= 22, but I think 21 is also safe. Smaller values
210238 // may still be safe, but it's more difficult to reason about them.
@@ -241,10 +269,21 @@ pub fn d2d(ieee_mantissa: u64, ieee_exponent: u32) -> FloatingDecimal64 {
241269 DOUBLE_POW5_SPLIT . get_unchecked ( i as usize )
242270 } ,
243271 j as u32 ,
244- & mut vp,
245- & mut vm,
272+ #[ cfg( maybe_uninit) ]
273+ { vp_uninit. as_mut_ptr ( ) } ,
274+ #[ cfg( not( maybe_uninit) ) ]
275+ { & mut vp } ,
276+ #[ cfg( maybe_uninit) ]
277+ { vm_uninit. as_mut_ptr ( ) } ,
278+ #[ cfg( not( maybe_uninit) ) ]
279+ { & mut vm } ,
246280 mm_shift,
247281 ) ;
282+ #[ cfg( maybe_uninit) ]
283+ {
284+ vp = unsafe { vp_uninit. assume_init ( ) } ;
285+ vm = unsafe { vm_uninit. assume_init ( ) } ;
286+ }
248287 if q <= 1 {
249288 // {vr,vp,vm} is trailing zeros if {mv,mp,mm} has at least q trailing 0 bits.
250289 // mv = 4 * m2, so it always has at least two trailing 0 bits.
0 commit comments