finish traits macros
authorJacob Lifshay <programmerjake@gmail.com>
Sun, 2 May 2021 23:01:10 +0000 (16:01 -0700)
committerJacob Lifshay <programmerjake@gmail.com>
Sun, 2 May 2021 23:01:10 +0000 (16:01 -0700)
src/traits.rs

index d5c7b77f5614a15bcb857095292e38fdf0a5134c..b8eb99da065bd19f75a22fa548d50bcb07ea9fd7 100644 (file)
@@ -5,6 +5,216 @@ use core::ops::{
 
 use crate::F16;
 
+#[rustfmt::skip] // work around for https://github.com/rust-lang/rustfmt/issues/4823
+macro_rules! make_float_type {
+    (
+        #[u32 = $u32:ident]
+        #[bool = $bool:ident]
+        [
+            $({
+                #[uint]
+                $uint_smaller:ident;
+                #[int]
+                $int_smaller:ident;
+                $(
+                    #[float]
+                    $float_smaller:ident;
+                )?
+            },)*
+        ],
+        {
+            #[uint]
+            $uint:ident;
+            #[int]
+            $int:ident;
+            #[float(prim = $float_prim:ident $(, scalar = $float_scalar:ident)?)]
+            $float:ident;
+        },
+        [
+            $({
+                #[uint]
+                $uint_larger:ident;
+                #[int]
+                $int_larger:ident;
+                $(
+                    #[float]
+                    $float_larger:ident;
+                )?
+            },)*
+        ]
+    ) => {
+        type $float: Float<Self::$u32, BitsType = Self::$uint>
+            $(+ From<Self::$float_scalar>)?
+            + Compare<Bool = Self::$bool>
+            + Make<Self, Prim = $float_prim>
+            $(+ ConvertTo<Self::$uint_smaller>)*
+            $(+ ConvertTo<Self::$int_smaller>)*
+            $($(+ ConvertTo<Self::$float_smaller>)?)*
+            + ConvertTo<Self::$uint>
+            + ConvertTo<Self::$int>
+            $(+ ConvertTo<Self::$uint_larger>)*
+            $(+ ConvertTo<Self::$int_larger>)*
+            $($(+ Into<Self::$float_larger>)?)*;
+    };
+    (
+        #[u32 = $u32:ident]
+        #[bool = $bool:ident]
+        [$($smaller:tt,)*],
+        {
+            #[uint]
+            $uint:ident;
+            #[int]
+            $int:ident;
+        },
+        [$($larger:tt,)*]
+    ) => {};
+}
+
+#[rustfmt::skip] // work around for https://github.com/rust-lang/rustfmt/issues/4823
+macro_rules! make_uint_int_float_type {
+    (
+        #[u32 = $u32:ident]
+        #[bool = $bool:ident]
+        [
+            $({
+                #[uint($($uint_smaller_traits:tt)*)]
+                $uint_smaller:ident;
+                #[int($($int_smaller_traits:tt)*)]
+                $int_smaller:ident;
+                $(
+                    #[float($($float_smaller_traits:tt)*)]
+                    $float_smaller:ident;
+                )?
+            },)*
+        ],
+        {
+            #[uint(prim = $uint_prim:ident $(, scalar = $uint_scalar:ident)?)]
+            $uint:ident;
+            #[int(prim = $int_prim:ident $(, scalar = $int_scalar:ident)?)]
+            $int:ident;
+            $(
+                #[float(prim = $float_prim:ident $(, scalar = $float_scalar:ident)?)]
+                $float:ident;
+            )?
+        },
+        [
+            $({
+                #[uint($($uint_larger_traits:tt)*)]
+                $uint_larger:ident;
+                #[int($($int_larger_traits:tt)*)]
+                $int_larger:ident;
+                $(
+                    #[float($($float_larger_traits:tt)*)]
+                    $float_larger:ident;
+                )?
+            },)*
+        ]
+    ) => {
+        type $uint: UInt<Self::$u32>
+            $(+ From<Self::$uint_scalar>)?
+            + Compare<Bool = Self::$bool>
+            + Make<Self, Prim = $uint_prim>
+            $(+ ConvertTo<Self::$uint_smaller>)*
+            $(+ ConvertTo<Self::$int_smaller>)*
+            $($(+ ConvertTo<Self::$float_smaller>)?)*
+            + ConvertTo<Self::$int>
+            $(+ ConvertTo<Self::$float>)?
+            $(+ Into<Self::$uint_larger>)*
+            $(+ Into<Self::$int_larger>)*
+            $($(+ Into<Self::$float_larger>)?)*;
+        type $int: SInt<Self::$u32>
+            $(+ From<Self::$int_scalar>)?
+            + Compare<Bool = Self::$bool>
+            + Make<Self, Prim = $int_prim>
+            $(+ ConvertTo<Self::$uint_smaller>)*
+            $(+ ConvertTo<Self::$int_smaller>)*
+            $($(+ ConvertTo<Self::$float_smaller>)?)*
+            + ConvertTo<Self::$uint>
+            $(+ ConvertTo<Self::$float>)?
+            $(+ ConvertTo<Self::$uint_larger>)*
+            $(+ Into<Self::$int_larger>)*
+            $($(+ Into<Self::$float_larger>)?)*;
+        make_float_type! {
+            #[u32 = $u32]
+            #[bool = $bool]
+            [
+                $({
+                    #[uint]
+                    $uint_smaller;
+                    #[int]
+                    $int_smaller;
+                    $(
+                        #[float]
+                        $float_smaller;
+                    )?
+                },)*
+            ],
+            {
+                #[uint]
+                $uint;
+                #[int]
+                $int;
+                $(
+                    #[float(prim = $float_prim $(, scalar = $float_scalar)?)]
+                    $float;
+                )?
+            },
+            [
+                $({
+                    #[uint]
+                    $uint_larger;
+                    #[int]
+                    $int_larger;
+                    $(
+                        #[float]
+                        $float_larger;
+                    )?
+                },)*
+            ]
+        }
+    };
+}
+
+macro_rules! make_uint_int_float_types {
+    (
+        #[u32 = $u32:ident]
+        #[bool = $bool:ident]
+        [$($smaller:tt,)*],
+        $current:tt,
+        [$first_larger:tt, $($larger:tt,)*]
+    ) => {
+        make_uint_int_float_type! {
+            #[u32 = $u32]
+            #[bool = $bool]
+            [$($smaller,)*],
+            $current,
+            [$first_larger, $($larger,)*]
+        }
+        make_uint_int_float_types! {
+            #[u32 = $u32]
+            #[bool = $bool]
+            [$($smaller,)* $current,],
+            $first_larger,
+            [$($larger,)*]
+        }
+    };
+    (
+        #[u32 = $u32:ident]
+        #[bool = $bool:ident]
+        [$($smaller:tt,)*],
+        $current:tt,
+        []
+    ) => {
+        make_uint_int_float_type! {
+            #[u32 = $u32]
+            #[bool = $bool]
+            [$($smaller,)*],
+            $current,
+            []
+        }
+    };
+}
+
 #[rustfmt::skip] // work around for https://github.com/rust-lang/rustfmt/issues/4823
 macro_rules! make_types {
     (
@@ -56,151 +266,48 @@ macro_rules! make_types {
         $(#[scalar = $ScalarF64:ident])?
         type $F64:ident;
     ) => {
-        type Bool: Bool + Make<Self, Prim = bool> + Select<Self::Bool>;
-        type U8: UInt<Self::U32>
-            + Compare<Bool = Self::Bool>
-            + Make<Self, Prim = u8>
-            + ConvertTo<Self::I8>
-            + Into<Self::U16>
-            + Into<Self::I16>
-            + Into<Self::F16>
-            + Into<Self::U32>
-            + Into<Self::I32>
-            + Into<Self::F32>
-            + Into<Self::U64>
-            + Into<Self::I64>
-            + Into<Self::F64>;
-        type U16: UInt<Self::U32>
-            + Compare<Bool = Self::Bool>
-            + Make<Self, Prim = u16>
-            + ConvertTo<Self::U8>
-            + ConvertTo<Self::I8>
-            + ConvertTo<Self::I16>
-            + ConvertTo<Self::F16>
-            + Into<Self::U32>
-            + Into<Self::I32>
-            + Into<Self::F32>
-            + Into<Self::U64>
-            + Into<Self::I64>
-            + Into<Self::F64>;
-        type U32: UInt<Self::U32>
-            + Compare<Bool = Self::Bool>
-            + Make<Self, Prim = u32>
-            + ConvertTo<Self::U8>
-            + ConvertTo<Self::I8>
-            + ConvertTo<Self::U16>
-            + ConvertTo<Self::I16>
-            + ConvertTo<Self::F16>
-            + ConvertTo<Self::I32>
-            + ConvertTo<Self::F32>
-            + Into<Self::U64>
-            + Into<Self::I64>
-            + Into<Self::F64>;
-        type U64: UInt<Self::U32>
-            + Compare<Bool = Self::Bool>
-            + Make<Self, Prim = u64>
-            + ConvertTo<Self::U8>
-            + ConvertTo<Self::I8>
-            + ConvertTo<Self::U16>
-            + ConvertTo<Self::I16>
-            + ConvertTo<Self::F16>
-            + ConvertTo<Self::U32>
-            + ConvertTo<Self::I32>
-            + ConvertTo<Self::F32>
-            + ConvertTo<Self::I64>
-            + ConvertTo<Self::F64>;
-        type I8: SInt<Self::U32>
-            + Compare<Bool = Self::Bool>
-            + Make<Self, Prim = i8>
-            + ConvertTo<Self::U8>
-            + ConvertTo<Self::U16>
-            + Into<Self::I16>
-            + Into<Self::F16>
-            + ConvertTo<Self::U32>
-            + Into<Self::I32>
-            + Into<Self::F32>
-            + ConvertTo<Self::U64>
-            + Into<Self::I64>
-            + Into<Self::F64>;
-        type I16: SInt<Self::U32>
-            + Compare<Bool = Self::Bool>
-            + Make<Self, Prim = i16>
-            + ConvertTo<Self::U8>
-            + ConvertTo<Self::I8>
-            + ConvertTo<Self::U16>
-            + ConvertTo<Self::F16>
-            + ConvertTo<Self::U32>
-            + Into<Self::I32>
-            + Into<Self::F32>
-            + ConvertTo<Self::U64>
-            + Into<Self::I64>
-            + Into<Self::F64>;
-        type I32: SInt<Self::U32>
-            + Compare<Bool = Self::Bool>
-            + Make<Self, Prim = i32>
-            + ConvertTo<Self::U8>
-            + ConvertTo<Self::I8>
-            + ConvertTo<Self::U16>
-            + ConvertTo<Self::I16>
-            + ConvertTo<Self::F16>
-            + ConvertTo<Self::U32>
-            + ConvertTo<Self::F32>
-            + ConvertTo<Self::U64>
-            + Into<Self::I64>
-            + Into<Self::F64>;
-        type I64: SInt<Self::U32>
-            + Compare<Bool = Self::Bool>
-            + Make<Self, Prim = i64>
-            + ConvertTo<Self::U8>
-            + ConvertTo<Self::I8>
-            + ConvertTo<Self::U16>
-            + ConvertTo<Self::I16>
-            + ConvertTo<Self::F16>
-            + ConvertTo<Self::U32>
-            + ConvertTo<Self::I32>
-            + ConvertTo<Self::F32>
-            + ConvertTo<Self::U64>
-            + ConvertTo<Self::F64>;
-        type F16: Float<Self::U32, BitsType = Self::U16>
-            + Compare<Bool = Self::Bool>
-            + Make<Self, Prim = F16>
-            + ConvertTo<Self::U8>
-            + ConvertTo<Self::I8>
-            + ConvertTo<Self::U16>
-            + ConvertTo<Self::I16>
-            + ConvertTo<Self::U32>
-            + ConvertTo<Self::I32>
-            + Into<Self::F32>
-            + ConvertTo<Self::U64>
-            + ConvertTo<Self::I64>
-            + Into<Self::F64>;
-        type F32: Float<Self::U32, BitsType = Self::U32>
-            + Compare<Bool = Self::Bool>
-            + Make<Self, Prim = f32>
-            + ConvertTo<Self::U8>
-            + ConvertTo<Self::I8>
-            + ConvertTo<Self::U16>
-            + ConvertTo<Self::I16>
-            + ConvertTo<Self::F16>
-            + ConvertTo<Self::U32>
-            + ConvertTo<Self::I32>
-            + ConvertTo<Self::U64>
-            + ConvertTo<Self::I64>
-            + Into<Self::F64>;
-        type F64: Float<Self::U32, BitsType = Self::U64>
-            + Compare<Bool = Self::Bool>
-            + Make<Self, Prim = f64>
-            + ConvertTo<Self::U8>
-            + ConvertTo<Self::I8>
-            + ConvertTo<Self::U16>
-            + ConvertTo<Self::I16>
-            + ConvertTo<Self::F16>
-            + ConvertTo<Self::U32>
-            + ConvertTo<Self::I32>
-            + ConvertTo<Self::F32>
-            + ConvertTo<Self::U64>
-            + ConvertTo<Self::I64>;
-        };
+        type $Bool: Bool
+            $(+ From<Self::$ScalarBool>)?
+            + Make<Self, Prim = bool>
+            + Select<Self::$Bool>;
+        make_uint_int_float_types! {
+            #[u32 = $U32]
+            #[bool = $Bool]
+            [],
+            {
+                #[uint(prim = u8 $(, scalar = $ScalarU8)?)]
+                $U8;
+                #[int(prim = i8 $(, scalar = $ScalarI8)?)]
+                $I8;
+            },
+            [
+                {
+                    #[uint(prim = u16 $(, scalar = $ScalarU16)?)]
+                    $U16;
+                    #[int(prim = i16 $(, scalar = $ScalarI16)?)]
+                    $I16;
+                    #[float(prim = F16 $(, scalar = $ScalarF16)?)]
+                    $F16;
+                },
+                {
+                    #[uint(prim = u32 $(, scalar = $ScalarU32)?)]
+                    $U32;
+                    #[int(prim = i32 $(, scalar = $ScalarI32)?)]
+                    $I32;
+                    #[float(prim = f32 $(, scalar = $ScalarF32)?)]
+                    $F32;
+                },
+                {
+                    #[uint(prim = u64 $(, scalar = $ScalarU64)?)]
+                    $U64;
+                    #[int(prim = i64 $(, scalar = $ScalarI64)?)]
+                    $I64;
+                    #[float(prim = f64 $(, scalar = $ScalarF64)?)]
+                    $F64;
+                },
+            ]
+        }
+    };
 }
 
 /// reference used to build IR for Kazan; an empty type for `core::simd`
@@ -244,234 +351,53 @@ pub trait Context: Copy {
     }
     make_types! {
         #[bool]
-        #[scalar = ScalarBool]
-        type Bool;
+        #[scalar = Bool]
+        type VecBool;
 
         #[u8]
-        #[scalar = ScalarU8]
-        type U8;
+        #[scalar = U8]
+        type VecU8;
 
         #[u16]
-        #[scalar = ScalarU16]
-        type U16;
+        #[scalar = U16]
+        type VecU16;
 
         #[u32]
-        #[scalar = ScalarU32]
-        type U32;
+        #[scalar = U32]
+        type VecU32;
 
         #[u64]
-        #[scalar = ScalarU64]
-        type U64;
+        #[scalar = U64]
+        type VecU64;
 
         #[i8]
-        #[scalar = ScalarI8]
-        type I8;
+        #[scalar = I8]
+        type VecI8;
 
         #[i16]
-        #[scalar = ScalarI16]
-        type I16;
+        #[scalar = I16]
+        type VecI16;
 
         #[i32]
-        #[scalar = ScalarI32]
-        type I32;
+        #[scalar = I32]
+        type VecI32;
 
         #[i64]
-        #[scalar = ScalarI64]
-        type I64;
+        #[scalar = I64]
+        type VecI64;
 
         #[f16]
-        #[scalar = ScalarF16]
-        type F16;
+        #[scalar = F16]
+        type VecF16;
 
         #[f32]
-        #[scalar = ScalarF32]
-        type F32;
+        #[scalar = F32]
+        type VecF32;
 
         #[f64]
-        #[scalar = ScalarF64]
-        type F64;
+        #[scalar = F64]
+        type VecF64;
     }
-    type Bool: Bool + Make<Self, Prim = bool> + Select<Self::Bool>;
-    type U8: UInt<Self::U32>
-        + Compare<Bool = Self::Bool>
-        + Make<Self, Prim = u8>
-        + ConvertTo<Self::I8>
-        + Into<Self::U16>
-        + Into<Self::I16>
-        + Into<Self::F16>
-        + Into<Self::U32>
-        + Into<Self::I32>
-        + Into<Self::F32>
-        + Into<Self::U64>
-        + Into<Self::I64>
-        + Into<Self::F64>;
-    type U16: UInt<Self::U32>
-        + Compare<Bool = Self::Bool>
-        + Make<Self, Prim = u16>
-        + ConvertTo<Self::U8>
-        + ConvertTo<Self::I8>
-        + ConvertTo<Self::I16>
-        + ConvertTo<Self::F16>
-        + Into<Self::U32>
-        + Into<Self::I32>
-        + Into<Self::F32>
-        + Into<Self::U64>
-        + Into<Self::I64>
-        + Into<Self::F64>;
-    type U32: UInt<Self::U32>
-        + Compare<Bool = Self::Bool>
-        + Make<Self, Prim = u32>
-        + ConvertTo<Self::U8>
-        + ConvertTo<Self::I8>
-        + ConvertTo<Self::U16>
-        + ConvertTo<Self::I16>
-        + ConvertTo<Self::F16>
-        + ConvertTo<Self::I32>
-        + ConvertTo<Self::F32>
-        + Into<Self::U64>
-        + Into<Self::I64>
-        + Into<Self::F64>;
-    type U64: UInt<Self::U32>
-        + Compare<Bool = Self::Bool>
-        + Make<Self, Prim = u64>
-        + ConvertTo<Self::U8>
-        + ConvertTo<Self::I8>
-        + ConvertTo<Self::U16>
-        + ConvertTo<Self::I16>
-        + ConvertTo<Self::F16>
-        + ConvertTo<Self::U32>
-        + ConvertTo<Self::I32>
-        + ConvertTo<Self::F32>
-        + ConvertTo<Self::I64>
-        + ConvertTo<Self::F64>;
-    type I8: SInt<Self::U32>
-        + Compare<Bool = Self::Bool>
-        + Make<Self, Prim = i8>
-        + ConvertTo<Self::U8>
-        + ConvertTo<Self::U16>
-        + Into<Self::I16>
-        + Into<Self::F16>
-        + ConvertTo<Self::U32>
-        + Into<Self::I32>
-        + Into<Self::F32>
-        + ConvertTo<Self::U64>
-        + Into<Self::I64>
-        + Into<Self::F64>;
-    type I16: SInt<Self::U32>
-        + Compare<Bool = Self::Bool>
-        + Make<Self, Prim = i16>
-        + ConvertTo<Self::U8>
-        + ConvertTo<Self::I8>
-        + ConvertTo<Self::U16>
-        + ConvertTo<Self::F16>
-        + ConvertTo<Self::U32>
-        + Into<Self::I32>
-        + Into<Self::F32>
-        + ConvertTo<Self::U64>
-        + Into<Self::I64>
-        + Into<Self::F64>;
-    type I32: SInt<Self::U32>
-        + Compare<Bool = Self::Bool>
-        + Make<Self, Prim = i32>
-        + ConvertTo<Self::U8>
-        + ConvertTo<Self::I8>
-        + ConvertTo<Self::U16>
-        + ConvertTo<Self::I16>
-        + ConvertTo<Self::F16>
-        + ConvertTo<Self::U32>
-        + ConvertTo<Self::F32>
-        + ConvertTo<Self::U64>
-        + Into<Self::I64>
-        + Into<Self::F64>;
-    type I64: SInt<Self::U32>
-        + Compare<Bool = Self::Bool>
-        + Make<Self, Prim = i64>
-        + ConvertTo<Self::U8>
-        + ConvertTo<Self::I8>
-        + ConvertTo<Self::U16>
-        + ConvertTo<Self::I16>
-        + ConvertTo<Self::F16>
-        + ConvertTo<Self::U32>
-        + ConvertTo<Self::I32>
-        + ConvertTo<Self::F32>
-        + ConvertTo<Self::U64>
-        + ConvertTo<Self::F64>;
-    type F16: Float<Self::U32, BitsType = Self::U16>
-        + Compare<Bool = Self::Bool>
-        + Make<Self, Prim = F16>
-        + ConvertTo<Self::U8>
-        + ConvertTo<Self::I8>
-        + ConvertTo<Self::U16>
-        + ConvertTo<Self::I16>
-        + ConvertTo<Self::U32>
-        + ConvertTo<Self::I32>
-        + Into<Self::F32>
-        + ConvertTo<Self::U64>
-        + ConvertTo<Self::I64>
-        + Into<Self::F64>;
-    type F32: Float<Self::U32, BitsType = Self::U32>
-        + Compare<Bool = Self::Bool>
-        + Make<Self, Prim = f32>
-        + ConvertTo<Self::U8>
-        + ConvertTo<Self::I8>
-        + ConvertTo<Self::U16>
-        + ConvertTo<Self::I16>
-        + ConvertTo<Self::F16>
-        + ConvertTo<Self::U32>
-        + ConvertTo<Self::I32>
-        + ConvertTo<Self::U64>
-        + ConvertTo<Self::I64>
-        + Into<Self::F64>;
-    type F64: Float<Self::U32, BitsType = Self::U64>
-        + Compare<Bool = Self::Bool>
-        + Make<Self, Prim = f64>
-        + ConvertTo<Self::U8>
-        + ConvertTo<Self::I8>
-        + ConvertTo<Self::U16>
-        + ConvertTo<Self::I16>
-        + ConvertTo<Self::F16>
-        + ConvertTo<Self::U32>
-        + ConvertTo<Self::I32>
-        + ConvertTo<Self::F32>
-        + ConvertTo<Self::U64>
-        + ConvertTo<Self::I64>;
-    // Vector types
-    type VecBool: From<Self::Bool> + Bool + Make<Self, Prim = bool> + Select<Self::VecBool>;
-    type VecU8: From<Self::U8>
-        + UInt<Self::VecU32>
-        + Compare<Bool = Self::VecBool>
-        + Make<Self, Prim = u8>;
-    type VecI8: From<Self::I8>
-        + SInt<Self::VecU32>
-        + Compare<Bool = Self::VecBool>
-        + Make<Self, Prim = i8>;
-    type VecU16: From<Self::U16>
-        + UInt<Self::VecU32>
-        + Compare<Bool = Self::VecBool>
-        + Make<Self, Prim = u16>;
-    type VecI16: From<Self::I16>
-        + SInt<Self::VecU32>
-        + Compare<Bool = Self::VecBool>
-        + Make<Self, Prim = i16>;
-    type VecF16: From<Self::F16> + Float + Compare<Bool = Self::VecBool> + Make<Self, Prim = F16>;
-    type VecU32: From<Self::U32>
-        + UInt<Self::VecU32>
-        + Compare<Bool = Self::VecBool>
-        + Make<Self, Prim = u32>;
-    type VecI32: From<Self::I32>
-        + SInt<Self::VecU32>
-        + Compare<Bool = Self::VecBool>
-        + Make<Self, Prim = i32>;
-    type VecF32: From<Self::F32> + Float + Compare<Bool = Self::VecBool> + Make<Self, Prim = f32>;
-    type VecU64: From<Self::U64>
-        + UInt<Self::VecU32>
-        + Compare<Bool = Self::VecBool>
-        + Make<Self, Prim = u64>;
-    type VecI64: From<Self::I64>
-        + SInt<Self::VecU32>
-        + Compare<Bool = Self::VecBool>
-        + Make<Self, Prim = i64>;
-    type VecF64: From<Self::F64> + Float + Compare<Bool = Self::VecBool> + Make<Self, Prim = f64>;
     fn make<T: Make<Self>>(self, v: T::Prim) -> T {
         T::make(self, v)
     }