Skip to content

Commit 2bed0e3

Browse files
committed
add f16
1 parent 022f250 commit 2bed0e3

File tree

12 files changed

+501
-36
lines changed

12 files changed

+501
-36
lines changed

build.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,8 @@ fn main() {
44
ac.emit_expression_cfg("1f64.total_cmp(&2f64)", "has_total_cmp"); // 1.62
55

66
autocfg::rerun_path("build.rs");
7+
8+
// FIXME: use autocfg to emit it
9+
println!("cargo:rustc-cfg=has_f16");
10+
println!("cargo:rustc-check-cfg=cfg(has_f16)");
711
}

src/bounds.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#[cfg(has_f16)]
2+
use core::f16;
13
use core::num::Wrapping;
24
use core::{f32, f64};
35
use core::{i128, i16, i32, i64, i8, isize};
@@ -77,7 +79,10 @@ impl<T: Bounded> Bounded for Wrapping<T> {
7779
}
7880
}
7981

82+
#[cfg(has_f16)]
83+
bounded_impl!(f16, f16::MIN, f16::MAX);
8084
bounded_impl!(f32, f32::MIN, f32::MAX);
85+
bounded_impl!(f64, f64::MIN, f64::MAX);
8186

8287
macro_rules! for_each_tuple_ {
8388
( $m:ident !! ) => (
@@ -110,7 +115,6 @@ macro_rules! bounded_tuple {
110115
}
111116

112117
for_each_tuple!(bounded_tuple);
113-
bounded_impl!(f64, f64::MIN, f64::MAX);
114118

115119
#[test]
116120
fn wrapping_bounded() {

src/cast.rs

Lines changed: 68 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#[cfg(has_f16)]
2+
use core::f16;
13
use core::mem::size_of;
24
use core::num::Wrapping;
35
use core::{f32, f64};
@@ -101,6 +103,15 @@ pub trait ToPrimitive {
101103
self.to_u64().map(From::from)
102104
}
103105

106+
/// Converts the value of `self` to an `f16`. Overflows may map to positive
107+
/// or negative inifinity, otherwise `None` is returned if the value cannot
108+
/// be represented by an `f16`.
109+
#[cfg(has_f16)]
110+
#[inline]
111+
fn to_f16(&self) -> Option<f16> {
112+
self.to_f64().as_ref().and_then(ToPrimitive::to_f16)
113+
}
114+
104115
/// Converts the value of `self` to an `f32`. Overflows may map to positive
105116
/// or negative inifinity, otherwise `None` is returned if the value cannot
106117
/// be represented by an `f32`.
@@ -177,6 +188,11 @@ macro_rules! impl_to_primitive_int {
177188
fn to_u128 -> u128;
178189
}
179190

191+
#[cfg(has_f16)]
192+
#[inline]
193+
fn to_f16(&self) -> Option<f16> {
194+
Some(*self as f16)
195+
}
180196
#[inline]
181197
fn to_f32(&self) -> Option<f32> {
182198
Some(*self as f32)
@@ -247,6 +263,11 @@ macro_rules! impl_to_primitive_uint {
247263
fn to_u128 -> u128;
248264
}
249265

266+
#[cfg(has_f16)]
267+
#[inline]
268+
fn to_f16(&self) -> Option<f16> {
269+
Some(*self as f16)
270+
}
250271
#[inline]
251272
fn to_f32(&self) -> Option<f32> {
252273
Some(*self as f32)
@@ -267,8 +288,9 @@ impl_to_primitive_uint!(u64);
267288
impl_to_primitive_uint!(u128);
268289

269290
macro_rules! impl_to_primitive_float_to_float {
270-
($SrcT:ident : $( fn $method:ident -> $DstT:ident ; )*) => {$(
291+
($SrcT:ident : $( $(#[$cfg:meta])* fn $method:ident -> $DstT:ident ; )*) => {$(
271292
#[inline]
293+
$(#[$cfg])*
272294
fn $method(&self) -> Option<$DstT> {
273295
// We can safely cast all values, whether NaN, +-inf, or finite.
274296
// Finite values that are reducing size may saturate to +-inf.
@@ -364,13 +386,17 @@ macro_rules! impl_to_primitive_float {
364386
}
365387

366388
impl_to_primitive_float_to_float! { $T:
389+
#[cfg(has_f16)]
390+
fn to_f16 -> f16;
367391
fn to_f32 -> f32;
368392
fn to_f64 -> f64;
369393
}
370394
}
371395
};
372396
}
373397

398+
#[cfg(has_f16)]
399+
impl_to_primitive_float!(f16);
374400
impl_to_primitive_float!(f32);
375401
impl_to_primitive_float!(f64);
376402

@@ -469,6 +495,14 @@ pub trait FromPrimitive: Sized {
469495
n.to_u64().and_then(FromPrimitive::from_u64)
470496
}
471497

498+
/// Converts a `f16` to return an optional value of this type. If the
499+
/// value cannot be represented by this type, then `None` is returned.
500+
#[cfg(has_f16)]
501+
#[inline]
502+
fn from_f16(n: f16) -> Option<Self> {
503+
FromPrimitive::from_f64(n as f64)
504+
}
505+
472506
/// Converts a `f32` to return an optional value of this type. If the
473507
/// value cannot be represented by this type, then `None` is returned.
474508
#[inline]
@@ -545,6 +579,11 @@ macro_rules! impl_from_primitive {
545579
n.$to_ty()
546580
}
547581

582+
#[cfg(has_f16)]
583+
#[inline]
584+
fn from_f16(n: f16) -> Option<$T> {
585+
n.$to_ty()
586+
}
548587
#[inline]
549588
fn from_f32(n: f32) -> Option<$T> {
550589
n.$to_ty()
@@ -569,6 +608,8 @@ impl_from_primitive!(u16, to_u16);
569608
impl_from_primitive!(u32, to_u32);
570609
impl_from_primitive!(u64, to_u64);
571610
impl_from_primitive!(u128, to_u128);
611+
#[cfg(has_f16)]
612+
impl_from_primitive!(f16, to_f16);
572613
impl_from_primitive!(f32, to_f32);
573614
impl_from_primitive!(f64, to_f64);
574615

@@ -598,6 +639,8 @@ impl<T: ToPrimitive> ToPrimitive for Wrapping<T> {
598639
fn to_u64 -> u64;
599640
fn to_u128 -> u128;
600641

642+
#[cfg(has_f16)]
643+
fn to_f16 -> f16;
601644
fn to_f32 -> f32;
602645
fn to_f64 -> f64;
603646
}
@@ -629,6 +672,8 @@ impl<T: FromPrimitive> FromPrimitive for Wrapping<T> {
629672
fn from_u64(u64);
630673
fn from_u128(u128);
631674

675+
#[cfg(has_f16)]
676+
fn from_f16(f16);
632677
fn from_f32(f32);
633678
fn from_f64(f64);
634679
}
@@ -692,6 +737,8 @@ impl_num_cast!(i32, to_i32);
692737
impl_num_cast!(i64, to_i64);
693738
impl_num_cast!(i128, to_i128);
694739
impl_num_cast!(isize, to_isize);
740+
#[cfg(has_f16)]
741+
impl_num_cast!(f16, to_f16);
695742
impl_num_cast!(f32, to_f32);
696743
impl_num_cast!(f64, to_f64);
697744

@@ -742,29 +789,31 @@ macro_rules! impl_as_primitive {
742789
#[inline] fn as_(self) -> $U { self as $U }
743790
}
744791
};
745-
(@ $T: ty => { $( $U: ty ),* } ) => {$(
746-
impl_as_primitive!(@ $T => impl $U);
792+
(@ $T: ty => { $( $(#[$cfg:meta])* $U: ty ),* } ) => {$(
793+
impl_as_primitive!(@ $T => $(#[$cfg])* impl $U);
747794
)*};
748-
($T: ty => { $( $U: ty ),* } ) => {
749-
impl_as_primitive!(@ $T => { $( $U ),* });
795+
($T: ty => { $( $(#[$cfg:meta])* $U: ty ),* } ) => {
796+
impl_as_primitive!(@ $T => { $( $(#[$cfg])* $U ),* });
750797
impl_as_primitive!(@ $T => { u8, u16, u32, u64, u128, usize });
751798
impl_as_primitive!(@ $T => { i8, i16, i32, i64, i128, isize });
752799
};
753800
}
754801

755-
impl_as_primitive!(u8 => { char, f32, f64 });
756-
impl_as_primitive!(i8 => { f32, f64 });
757-
impl_as_primitive!(u16 => { f32, f64 });
758-
impl_as_primitive!(i16 => { f32, f64 });
759-
impl_as_primitive!(u32 => { f32, f64 });
760-
impl_as_primitive!(i32 => { f32, f64 });
761-
impl_as_primitive!(u64 => { f32, f64 });
762-
impl_as_primitive!(i64 => { f32, f64 });
763-
impl_as_primitive!(u128 => { f32, f64 });
764-
impl_as_primitive!(i128 => { f32, f64 });
765-
impl_as_primitive!(usize => { f32, f64 });
766-
impl_as_primitive!(isize => { f32, f64 });
767-
impl_as_primitive!(f32 => { f32, f64 });
768-
impl_as_primitive!(f64 => { f32, f64 });
802+
impl_as_primitive!(u8 => { char, #[cfg(has_f16)] f16, f32, f64 });
803+
impl_as_primitive!(i8 => { #[cfg(has_f16)] f16, f32, f64 });
804+
impl_as_primitive!(u16 => { #[cfg(has_f16)] f16, f32, f64 });
805+
impl_as_primitive!(i16 => { #[cfg(has_f16)] f16, f32, f64 });
806+
impl_as_primitive!(u32 => { #[cfg(has_f16)] f16, f32, f64 });
807+
impl_as_primitive!(i32 => { #[cfg(has_f16)] f16, f32, f64 });
808+
impl_as_primitive!(u64 => { #[cfg(has_f16)] f16, f32, f64 });
809+
impl_as_primitive!(i64 => { #[cfg(has_f16)] f16, f32, f64 });
810+
impl_as_primitive!(u128 => { #[cfg(has_f16)] f16, f32, f64 });
811+
impl_as_primitive!(i128 => { #[cfg(has_f16)] f16, f32, f64 });
812+
impl_as_primitive!(usize => { #[cfg(has_f16)] f16, f32, f64 });
813+
impl_as_primitive!(isize => { #[cfg(has_f16)] f16, f32, f64 });
814+
#[cfg(has_f16)]
815+
impl_as_primitive!(f16 => { f16, f32, f64 });
816+
impl_as_primitive!(f32 => { #[cfg(has_f16)] f16, f32, f64 });
817+
impl_as_primitive!(f64 => { #[cfg(has_f16)] f16, f32, f64 });
769818
impl_as_primitive!(char => { char });
770819
impl_as_primitive!(bool => {});

0 commit comments

Comments
 (0)