@@ -156,22 +156,42 @@ impl_from!(i16 => isize, #[stable(feature = "lossless_iusize_conv", since = "1.2
156
156
// https://www.cl.cam.ac.uk/techreports/UCAM-CL-TR-951.pdf
157
157
158
158
// Note: integers can only be represented with full precision in a float if
159
- // they fit in the significand, which is 24 bits in f32 and 53 bits in f64.
159
+ // they fit in the significand, which is:
160
+ // * 11 bits in f16
161
+ // * 24 bits in f32
162
+ // * 53 bits in f64
163
+ // * 113 bits in f128
160
164
// Lossy float conversions are not implemented at this time.
165
+ // FIXME(f16_f128): The `f16`/`f128` impls `#[stable]` attributes should be changed to reference
166
+ // `f16`/`f128` when they are stabilised (trait impls have to have a `#[stable]` attribute, but none
167
+ // of the `f16`/`f128` impls can be used on stable as the `f16` and `f128` types are unstable).
161
168
162
169
// signed integer -> float
170
+ impl_from ! ( i8 => f16, #[ stable( feature = "lossless_float_conv" , since = "1.6.0" ) ] ) ;
163
171
impl_from ! ( i8 => f32 , #[ stable( feature = "lossless_float_conv" , since = "1.6.0" ) ] ) ;
164
172
impl_from ! ( i8 => f64 , #[ stable( feature = "lossless_float_conv" , since = "1.6.0" ) ] ) ;
173
+ impl_from ! ( i8 => f128, #[ stable( feature = "lossless_float_conv" , since = "1.6.0" ) ] ) ;
165
174
impl_from ! ( i16 => f32 , #[ stable( feature = "lossless_float_conv" , since = "1.6.0" ) ] ) ;
166
175
impl_from ! ( i16 => f64 , #[ stable( feature = "lossless_float_conv" , since = "1.6.0" ) ] ) ;
176
+ impl_from ! ( i16 => f128, #[ stable( feature = "lossless_float_conv" , since = "1.6.0" ) ] ) ;
167
177
impl_from ! ( i32 => f64 , #[ stable( feature = "lossless_float_conv" , since = "1.6.0" ) ] ) ;
178
+ impl_from ! ( i32 => f128, #[ stable( feature = "lossless_float_conv" , since = "1.6.0" ) ] ) ;
179
+ // FIXME(f16_f128): This impl would allow using `f128` on stable before it is stabilised.
180
+ // impl_from!(i64 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
168
181
169
182
// unsigned integer -> float
183
+ impl_from ! ( u8 => f16, #[ stable( feature = "lossless_float_conv" , since = "1.6.0" ) ] ) ;
170
184
impl_from ! ( u8 => f32 , #[ stable( feature = "lossless_float_conv" , since = "1.6.0" ) ] ) ;
171
185
impl_from ! ( u8 => f64 , #[ stable( feature = "lossless_float_conv" , since = "1.6.0" ) ] ) ;
186
+ impl_from ! ( u8 => f128, #[ stable( feature = "lossless_float_conv" , since = "1.6.0" ) ] ) ;
187
+ impl_from ! ( u16 => f16, #[ stable( feature = "lossless_float_conv" , since = "1.6.0" ) ] ) ;
172
188
impl_from ! ( u16 => f32 , #[ stable( feature = "lossless_float_conv" , since = "1.6.0" ) ] ) ;
173
189
impl_from ! ( u16 => f64 , #[ stable( feature = "lossless_float_conv" , since = "1.6.0" ) ] ) ;
190
+ impl_from ! ( u16 => f128, #[ stable( feature = "lossless_float_conv" , since = "1.6.0" ) ] ) ;
174
191
impl_from ! ( u32 => f64 , #[ stable( feature = "lossless_float_conv" , since = "1.6.0" ) ] ) ;
192
+ impl_from ! ( u32 => f128, #[ stable( feature = "lossless_float_conv" , since = "1.6.0" ) ] ) ;
193
+ // FIXME(f16_f128): This impl would allow using `f128` on stable before it is stabilised.
194
+ // impl_from!(u64 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
175
195
176
196
// float -> float
177
197
// FIXME(f16_f128): adding additional `From<{float}>` impls to `f32` breaks inference. See
@@ -183,20 +203,27 @@ impl_from!(f32 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0
183
203
impl_from ! ( f64 => f128, #[ stable( feature = "lossless_float_conv" , since = "1.6.0" ) ] ) ;
184
204
185
205
macro_rules! impl_float_from_bool {
186
- ( $float: ty) => {
206
+ (
207
+ $float: ty $( ;
208
+ doctest_prefix: $( #[ doc = $doctest_prefix: literal] ) *
209
+ doctest_suffix: $( #[ doc = $doctest_suffix: literal] ) *
210
+ ) ?
211
+ ) => {
187
212
#[ stable( feature = "float_from_bool" , since = "1.68.0" ) ]
188
213
impl From <bool > for $float {
189
214
#[ doc = concat!( "Converts a [`bool`] to [`" , stringify!( $float) , "`] losslessly." ) ]
190
215
/// The resulting value is positive `0.0` for `false` and `1.0` for `true` values.
191
216
///
192
217
/// # Examples
193
218
/// ```
219
+ $( $( #[ doc = $doctest_prefix] ) * ) ?
194
220
#[ doc = concat!( "let x: " , stringify!( $float) , " = false.into();" ) ]
195
221
/// assert_eq!(x, 0.0);
196
222
/// assert!(x.is_sign_positive());
197
223
///
198
224
#[ doc = concat!( "let y: " , stringify!( $float) , " = true.into();" ) ]
199
225
/// assert_eq!(y, 1.0);
226
+ $( $( #[ doc = $doctest_suffix] ) * ) ?
200
227
/// ```
201
228
#[ inline]
202
229
fn from( small: bool ) -> Self {
@@ -207,8 +234,27 @@ macro_rules! impl_float_from_bool {
207
234
}
208
235
209
236
// boolean -> float
237
+ impl_float_from_bool ! (
238
+ f16;
239
+ doctest_prefix:
240
+ // rustdoc doesn't remove the conventional space after the `///`
241
+ ///#![feature(f16)]
242
+ ///# #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
243
+ ///
244
+ doctest_suffix:
245
+ ///# }
246
+ ) ;
210
247
impl_float_from_bool ! ( f32 ) ;
211
248
impl_float_from_bool ! ( f64 ) ;
249
+ impl_float_from_bool ! (
250
+ f128;
251
+ doctest_prefix:
252
+ ///#![feature(f128)]
253
+ ///# #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
254
+ ///
255
+ doctest_suffix:
256
+ ///# }
257
+ ) ;
212
258
213
259
// no possible bounds violation
214
260
macro_rules! impl_try_from_unbounded {
0 commit comments