1 //! A type-level array of type-level numbers. 2 //! 3 //! It is not very featureful right now, and should be considered a work in progress. 4 5 use core::marker::PhantomData; 6 use core::ops::{Add, Div, Mul, Sub}; 7 8 use super::*; 9 10 /// The terminating type for type arrays. 11 #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug)] 12 pub struct ATerm; 13 14 impl TypeArray for ATerm {} 15 16 /// `TArr` is a type that acts as an array of types. It is defined similarly to `UInt`, only its 17 /// values can be more than bits, and it is designed to act as an array. So you can only add two if 18 /// they have the same number of elements, for example. 19 /// 20 /// This array is only really designed to contain `Integer` types. If you use it with others, you 21 /// may find it lacking functionality. 22 #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug)] 23 pub struct TArr<V, A> { 24 _marker: PhantomData<(V, A)>, 25 } 26 27 impl<V, A> TypeArray for TArr<V, A> {} 28 29 /// Create a new type-level arrray. Only usable on Rust 1.13.0 or newer. 30 /// 31 /// There's not a whole lot you can do with it right now. 32 /// 33 /// # Example 34 /// ```rust 35 /// #[macro_use] 36 /// extern crate typenum; 37 /// use typenum::consts::*; 38 /// 39 /// type Array = tarr![P3, N4, Z0, P38]; 40 /// # fn main() { let _: Array; } 41 #[macro_export] 42 macro_rules! tarr { 43 () => ( $crate::ATerm ); 44 ($n:ty) => ( $crate::TArr<$n, $crate::ATerm> ); 45 ($n:ty,) => ( $crate::TArr<$n, $crate::ATerm> ); 46 ($n:ty, $($tail:ty),+) => ( $crate::TArr<$n, tarr![$($tail),+]> ); 47 ($n:ty, $($tail:ty),+,) => ( $crate::TArr<$n, tarr![$($tail),+]> ); 48 } 49 50 // --------------------------------------------------------------------------------------- 51 // Length 52 53 /// Length of `ATerm` by itself is 0 54 impl Len for ATerm { 55 type Output = U0; len(&self) -> Self::Output56 fn len(&self) -> Self::Output { 57 UTerm 58 } 59 } 60 61 /// Size of a `TypeArray` 62 impl<V, A> Len for TArr<V, A> 63 where 64 A: Len, 65 Length<A>: Add<B1>, 66 Sum<Length<A>, B1>: Unsigned, 67 { 68 type Output = Add1<Length<A>>; len(&self) -> Self::Output69 fn len(&self) -> Self::Output { 70 unsafe { ::core::mem::uninitialized() } 71 } 72 } 73 74 // --------------------------------------------------------------------------------------- 75 // Add arrays 76 // Note that two arrays are only addable if they are the same length. 77 78 impl Add<ATerm> for ATerm { 79 type Output = ATerm; add(self, _: ATerm) -> Self::Output80 fn add(self, _: ATerm) -> Self::Output { 81 ATerm 82 } 83 } 84 85 impl<Al, Vl, Ar, Vr> Add<TArr<Vr, Ar>> for TArr<Vl, Al> 86 where 87 Al: Add<Ar>, 88 Vl: Add<Vr>, 89 { 90 type Output = TArr<Sum<Vl, Vr>, Sum<Al, Ar>>; add(self, _: TArr<Vr, Ar>) -> Self::Output91 fn add(self, _: TArr<Vr, Ar>) -> Self::Output { 92 unsafe { ::core::mem::uninitialized() } 93 } 94 } 95 96 // --------------------------------------------------------------------------------------- 97 // Subtract arrays 98 // Note that two arrays are only subtractable if they are the same length. 99 100 impl Sub<ATerm> for ATerm { 101 type Output = ATerm; sub(self, _: ATerm) -> Self::Output102 fn sub(self, _: ATerm) -> Self::Output { 103 ATerm 104 } 105 } 106 107 impl<Vl, Al, Vr, Ar> Sub<TArr<Vr, Ar>> for TArr<Vl, Al> 108 where 109 Vl: Sub<Vr>, 110 Al: Sub<Ar>, 111 { 112 type Output = TArr<Diff<Vl, Vr>, Diff<Al, Ar>>; sub(self, _: TArr<Vr, Ar>) -> Self::Output113 fn sub(self, _: TArr<Vr, Ar>) -> Self::Output { 114 unsafe { ::core::mem::uninitialized() } 115 } 116 } 117 118 // --------------------------------------------------------------------------------------- 119 // Multiply an array by a scalar 120 121 impl<Rhs> Mul<Rhs> for ATerm { 122 type Output = ATerm; mul(self, _: Rhs) -> Self::Output123 fn mul(self, _: Rhs) -> Self::Output { 124 ATerm 125 } 126 } 127 128 impl<V, A, Rhs> Mul<Rhs> for TArr<V, A> 129 where 130 V: Mul<Rhs>, 131 A: Mul<Rhs>, 132 { 133 type Output = TArr<Prod<V, Rhs>, Prod<A, Rhs>>; mul(self, _: Rhs) -> Self::Output134 fn mul(self, _: Rhs) -> Self::Output { 135 unsafe { ::core::mem::uninitialized() } 136 } 137 } 138 139 impl Mul<ATerm> for Z0 { 140 type Output = ATerm; mul(self, _: ATerm) -> Self::Output141 fn mul(self, _: ATerm) -> Self::Output { 142 ATerm 143 } 144 } 145 146 impl<U> Mul<ATerm> for PInt<U> 147 where 148 U: Unsigned + NonZero, 149 { 150 type Output = ATerm; mul(self, _: ATerm) -> Self::Output151 fn mul(self, _: ATerm) -> Self::Output { 152 ATerm 153 } 154 } 155 156 impl<U> Mul<ATerm> for NInt<U> 157 where 158 U: Unsigned + NonZero, 159 { 160 type Output = ATerm; mul(self, _: ATerm) -> Self::Output161 fn mul(self, _: ATerm) -> Self::Output { 162 ATerm 163 } 164 } 165 166 impl<V, A> Mul<TArr<V, A>> for Z0 167 where 168 Z0: Mul<A>, 169 { 170 type Output = TArr<Z0, Prod<Z0, A>>; mul(self, _: TArr<V, A>) -> Self::Output171 fn mul(self, _: TArr<V, A>) -> Self::Output { 172 unsafe { ::core::mem::uninitialized() } 173 } 174 } 175 176 impl<V, A, U> Mul<TArr<V, A>> for PInt<U> 177 where 178 U: Unsigned + NonZero, 179 PInt<U>: Mul<A> + Mul<V>, 180 { 181 type Output = TArr<Prod<PInt<U>, V>, Prod<PInt<U>, A>>; mul(self, _: TArr<V, A>) -> Self::Output182 fn mul(self, _: TArr<V, A>) -> Self::Output { 183 unsafe { ::core::mem::uninitialized() } 184 } 185 } 186 187 impl<V, A, U> Mul<TArr<V, A>> for NInt<U> 188 where 189 U: Unsigned + NonZero, 190 NInt<U>: Mul<A> + Mul<V>, 191 { 192 type Output = TArr<Prod<NInt<U>, V>, Prod<NInt<U>, A>>; mul(self, _: TArr<V, A>) -> Self::Output193 fn mul(self, _: TArr<V, A>) -> Self::Output { 194 unsafe { ::core::mem::uninitialized() } 195 } 196 } 197 198 // --------------------------------------------------------------------------------------- 199 // Divide an array by a scalar 200 201 impl<Rhs> Div<Rhs> for ATerm { 202 type Output = ATerm; div(self, _: Rhs) -> Self::Output203 fn div(self, _: Rhs) -> Self::Output { 204 ATerm 205 } 206 } 207 208 impl<V, A, Rhs> Div<Rhs> for TArr<V, A> 209 where 210 V: Div<Rhs>, 211 A: Div<Rhs>, 212 { 213 type Output = TArr<Quot<V, Rhs>, Quot<A, Rhs>>; div(self, _: Rhs) -> Self::Output214 fn div(self, _: Rhs) -> Self::Output { 215 unsafe { ::core::mem::uninitialized() } 216 } 217 } 218 219 // --------------------------------------------------------------------------------------- 220 // Partial Divide an array by a scalar 221 222 impl<Rhs> PartialDiv<Rhs> for ATerm { 223 type Output = ATerm; partial_div(self, _: Rhs) -> Self::Output224 fn partial_div(self, _: Rhs) -> Self::Output { 225 ATerm 226 } 227 } 228 229 impl<V, A, Rhs> PartialDiv<Rhs> for TArr<V, A> 230 where 231 V: PartialDiv<Rhs>, 232 A: PartialDiv<Rhs>, 233 { 234 type Output = TArr<PartialQuot<V, Rhs>, PartialQuot<A, Rhs>>; partial_div(self, _: Rhs) -> Self::Output235 fn partial_div(self, _: Rhs) -> Self::Output { 236 unsafe { ::core::mem::uninitialized() } 237 } 238 } 239 240 // --------------------------------------------------------------------------------------- 241 // Modulo an array by a scalar 242 use core::ops::Rem; 243 244 impl<Rhs> Rem<Rhs> for ATerm { 245 type Output = ATerm; rem(self, _: Rhs) -> Self::Output246 fn rem(self, _: Rhs) -> Self::Output { 247 ATerm 248 } 249 } 250 251 impl<V, A, Rhs> Rem<Rhs> for TArr<V, A> 252 where 253 V: Rem<Rhs>, 254 A: Rem<Rhs>, 255 { 256 type Output = TArr<Mod<V, Rhs>, Mod<A, Rhs>>; rem(self, _: Rhs) -> Self::Output257 fn rem(self, _: Rhs) -> Self::Output { 258 unsafe { ::core::mem::uninitialized() } 259 } 260 } 261 262 // --------------------------------------------------------------------------------------- 263 // Negate an array 264 use core::ops::Neg; 265 266 impl Neg for ATerm { 267 type Output = ATerm; neg(self) -> Self::Output268 fn neg(self) -> Self::Output { 269 ATerm 270 } 271 } 272 273 impl<V, A> Neg for TArr<V, A> 274 where 275 V: Neg, 276 A: Neg, 277 { 278 type Output = TArr<Negate<V>, Negate<A>>; neg(self) -> Self::Output279 fn neg(self) -> Self::Output { 280 unsafe { ::core::mem::uninitialized() } 281 } 282 } 283