working on code
[vector-math.git] / src / traits.rs
1 use core::ops::{
2 Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign,
3 Mul, MulAssign, Neg, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign,
4 };
5
6 use crate::F16;
7
8 #[rustfmt::skip] // work around for https://github.com/rust-lang/rustfmt/issues/4823
9 macro_rules! make_types {
10 (
11 #[bool]
12 $(#[scalar = $ScalarBool:ident])?
13 type $Bool:ident;
14
15 #[u8]
16 $(#[scalar = $ScalarU8:ident])?
17 type $U8:ident;
18
19 #[u16]
20 $(#[scalar = $ScalarU16:ident])?
21 type $U16:ident;
22
23 #[u32]
24 $(#[scalar = $ScalarU32:ident])?
25 type $U32:ident;
26
27 #[u64]
28 $(#[scalar = $ScalarU64:ident])?
29 type $U64:ident;
30
31 #[i8]
32 $(#[scalar = $ScalarI8:ident])?
33 type $I8:ident;
34
35 #[i16]
36 $(#[scalar = $ScalarI16:ident])?
37 type $I16:ident;
38
39 #[i32]
40 $(#[scalar = $ScalarI32:ident])?
41 type $I32:ident;
42
43 #[i64]
44 $(#[scalar = $ScalarI64:ident])?
45 type $I64:ident;
46
47 #[f16]
48 $(#[scalar = $ScalarF16:ident])?
49 type $F16:ident;
50
51 #[f32]
52 $(#[scalar = $ScalarF32:ident])?
53 type $F32:ident;
54
55 #[f64]
56 $(#[scalar = $ScalarF64:ident])?
57 type $F64:ident;
58 ) => {
59 type Bool: Bool + Make<Self, Prim = bool> + Select<Self::Bool>;
60 type U8: UInt<Self::U32>
61 + Compare<Bool = Self::Bool>
62 + Make<Self, Prim = u8>
63 + ConvertTo<Self::I8>
64 + Into<Self::U16>
65 + Into<Self::I16>
66 + Into<Self::F16>
67 + Into<Self::U32>
68 + Into<Self::I32>
69 + Into<Self::F32>
70 + Into<Self::U64>
71 + Into<Self::I64>
72 + Into<Self::F64>;
73 type U16: UInt<Self::U32>
74 + Compare<Bool = Self::Bool>
75 + Make<Self, Prim = u16>
76 + ConvertTo<Self::U8>
77 + ConvertTo<Self::I8>
78 + ConvertTo<Self::I16>
79 + ConvertTo<Self::F16>
80 + Into<Self::U32>
81 + Into<Self::I32>
82 + Into<Self::F32>
83 + Into<Self::U64>
84 + Into<Self::I64>
85 + Into<Self::F64>;
86 type U32: UInt<Self::U32>
87 + Compare<Bool = Self::Bool>
88 + Make<Self, Prim = u32>
89 + ConvertTo<Self::U8>
90 + ConvertTo<Self::I8>
91 + ConvertTo<Self::U16>
92 + ConvertTo<Self::I16>
93 + ConvertTo<Self::F16>
94 + ConvertTo<Self::I32>
95 + ConvertTo<Self::F32>
96 + Into<Self::U64>
97 + Into<Self::I64>
98 + Into<Self::F64>;
99 type U64: UInt<Self::U32>
100 + Compare<Bool = Self::Bool>
101 + Make<Self, Prim = u64>
102 + ConvertTo<Self::U8>
103 + ConvertTo<Self::I8>
104 + ConvertTo<Self::U16>
105 + ConvertTo<Self::I16>
106 + ConvertTo<Self::F16>
107 + ConvertTo<Self::U32>
108 + ConvertTo<Self::I32>
109 + ConvertTo<Self::F32>
110 + ConvertTo<Self::I64>
111 + ConvertTo<Self::F64>;
112 type I8: SInt<Self::U32>
113 + Compare<Bool = Self::Bool>
114 + Make<Self, Prim = i8>
115 + ConvertTo<Self::U8>
116 + ConvertTo<Self::U16>
117 + Into<Self::I16>
118 + Into<Self::F16>
119 + ConvertTo<Self::U32>
120 + Into<Self::I32>
121 + Into<Self::F32>
122 + ConvertTo<Self::U64>
123 + Into<Self::I64>
124 + Into<Self::F64>;
125 type I16: SInt<Self::U32>
126 + Compare<Bool = Self::Bool>
127 + Make<Self, Prim = i16>
128 + ConvertTo<Self::U8>
129 + ConvertTo<Self::I8>
130 + ConvertTo<Self::U16>
131 + ConvertTo<Self::F16>
132 + ConvertTo<Self::U32>
133 + Into<Self::I32>
134 + Into<Self::F32>
135 + ConvertTo<Self::U64>
136 + Into<Self::I64>
137 + Into<Self::F64>;
138 type I32: SInt<Self::U32>
139 + Compare<Bool = Self::Bool>
140 + Make<Self, Prim = i32>
141 + ConvertTo<Self::U8>
142 + ConvertTo<Self::I8>
143 + ConvertTo<Self::U16>
144 + ConvertTo<Self::I16>
145 + ConvertTo<Self::F16>
146 + ConvertTo<Self::U32>
147 + ConvertTo<Self::F32>
148 + ConvertTo<Self::U64>
149 + Into<Self::I64>
150 + Into<Self::F64>;
151 type I64: SInt<Self::U32>
152 + Compare<Bool = Self::Bool>
153 + Make<Self, Prim = i64>
154 + ConvertTo<Self::U8>
155 + ConvertTo<Self::I8>
156 + ConvertTo<Self::U16>
157 + ConvertTo<Self::I16>
158 + ConvertTo<Self::F16>
159 + ConvertTo<Self::U32>
160 + ConvertTo<Self::I32>
161 + ConvertTo<Self::F32>
162 + ConvertTo<Self::U64>
163 + ConvertTo<Self::F64>;
164 type F16: Float<Self::U32, BitsType = Self::U16>
165 + Compare<Bool = Self::Bool>
166 + Make<Self, Prim = F16>
167 + ConvertTo<Self::U8>
168 + ConvertTo<Self::I8>
169 + ConvertTo<Self::U16>
170 + ConvertTo<Self::I16>
171 + ConvertTo<Self::U32>
172 + ConvertTo<Self::I32>
173 + Into<Self::F32>
174 + ConvertTo<Self::U64>
175 + ConvertTo<Self::I64>
176 + Into<Self::F64>;
177 type F32: Float<Self::U32, BitsType = Self::U32>
178 + Compare<Bool = Self::Bool>
179 + Make<Self, Prim = f32>
180 + ConvertTo<Self::U8>
181 + ConvertTo<Self::I8>
182 + ConvertTo<Self::U16>
183 + ConvertTo<Self::I16>
184 + ConvertTo<Self::F16>
185 + ConvertTo<Self::U32>
186 + ConvertTo<Self::I32>
187 + ConvertTo<Self::U64>
188 + ConvertTo<Self::I64>
189 + Into<Self::F64>;
190 type F64: Float<Self::U32, BitsType = Self::U64>
191 + Compare<Bool = Self::Bool>
192 + Make<Self, Prim = f64>
193 + ConvertTo<Self::U8>
194 + ConvertTo<Self::I8>
195 + ConvertTo<Self::U16>
196 + ConvertTo<Self::I16>
197 + ConvertTo<Self::F16>
198 + ConvertTo<Self::U32>
199 + ConvertTo<Self::I32>
200 + ConvertTo<Self::F32>
201 + ConvertTo<Self::U64>
202 + ConvertTo<Self::I64>;
203 };
204 }
205
206 /// reference used to build IR for Kazan; an empty type for `core::simd`
207 pub trait Context: Copy {
208 make_types! {
209 #[bool]
210 type Bool;
211
212 #[u8]
213 type U8;
214
215 #[u16]
216 type U16;
217
218 #[u32]
219 type U32;
220
221 #[u64]
222 type U64;
223
224 #[i8]
225 type I8;
226
227 #[i16]
228 type I16;
229
230 #[i32]
231 type I32;
232
233 #[i64]
234 type I64;
235
236 #[f16]
237 type F16;
238
239 #[f32]
240 type F32;
241
242 #[f64]
243 type F64;
244 }
245 make_types! {
246 #[bool]
247 #[scalar = ScalarBool]
248 type Bool;
249
250 #[u8]
251 #[scalar = ScalarU8]
252 type U8;
253
254 #[u16]
255 #[scalar = ScalarU16]
256 type U16;
257
258 #[u32]
259 #[scalar = ScalarU32]
260 type U32;
261
262 #[u64]
263 #[scalar = ScalarU64]
264 type U64;
265
266 #[i8]
267 #[scalar = ScalarI8]
268 type I8;
269
270 #[i16]
271 #[scalar = ScalarI16]
272 type I16;
273
274 #[i32]
275 #[scalar = ScalarI32]
276 type I32;
277
278 #[i64]
279 #[scalar = ScalarI64]
280 type I64;
281
282 #[f16]
283 #[scalar = ScalarF16]
284 type F16;
285
286 #[f32]
287 #[scalar = ScalarF32]
288 type F32;
289
290 #[f64]
291 #[scalar = ScalarF64]
292 type F64;
293 }
294 type Bool: Bool + Make<Self, Prim = bool> + Select<Self::Bool>;
295 type U8: UInt<Self::U32>
296 + Compare<Bool = Self::Bool>
297 + Make<Self, Prim = u8>
298 + ConvertTo<Self::I8>
299 + Into<Self::U16>
300 + Into<Self::I16>
301 + Into<Self::F16>
302 + Into<Self::U32>
303 + Into<Self::I32>
304 + Into<Self::F32>
305 + Into<Self::U64>
306 + Into<Self::I64>
307 + Into<Self::F64>;
308 type U16: UInt<Self::U32>
309 + Compare<Bool = Self::Bool>
310 + Make<Self, Prim = u16>
311 + ConvertTo<Self::U8>
312 + ConvertTo<Self::I8>
313 + ConvertTo<Self::I16>
314 + ConvertTo<Self::F16>
315 + Into<Self::U32>
316 + Into<Self::I32>
317 + Into<Self::F32>
318 + Into<Self::U64>
319 + Into<Self::I64>
320 + Into<Self::F64>;
321 type U32: UInt<Self::U32>
322 + Compare<Bool = Self::Bool>
323 + Make<Self, Prim = u32>
324 + ConvertTo<Self::U8>
325 + ConvertTo<Self::I8>
326 + ConvertTo<Self::U16>
327 + ConvertTo<Self::I16>
328 + ConvertTo<Self::F16>
329 + ConvertTo<Self::I32>
330 + ConvertTo<Self::F32>
331 + Into<Self::U64>
332 + Into<Self::I64>
333 + Into<Self::F64>;
334 type U64: UInt<Self::U32>
335 + Compare<Bool = Self::Bool>
336 + Make<Self, Prim = u64>
337 + ConvertTo<Self::U8>
338 + ConvertTo<Self::I8>
339 + ConvertTo<Self::U16>
340 + ConvertTo<Self::I16>
341 + ConvertTo<Self::F16>
342 + ConvertTo<Self::U32>
343 + ConvertTo<Self::I32>
344 + ConvertTo<Self::F32>
345 + ConvertTo<Self::I64>
346 + ConvertTo<Self::F64>;
347 type I8: SInt<Self::U32>
348 + Compare<Bool = Self::Bool>
349 + Make<Self, Prim = i8>
350 + ConvertTo<Self::U8>
351 + ConvertTo<Self::U16>
352 + Into<Self::I16>
353 + Into<Self::F16>
354 + ConvertTo<Self::U32>
355 + Into<Self::I32>
356 + Into<Self::F32>
357 + ConvertTo<Self::U64>
358 + Into<Self::I64>
359 + Into<Self::F64>;
360 type I16: SInt<Self::U32>
361 + Compare<Bool = Self::Bool>
362 + Make<Self, Prim = i16>
363 + ConvertTo<Self::U8>
364 + ConvertTo<Self::I8>
365 + ConvertTo<Self::U16>
366 + ConvertTo<Self::F16>
367 + ConvertTo<Self::U32>
368 + Into<Self::I32>
369 + Into<Self::F32>
370 + ConvertTo<Self::U64>
371 + Into<Self::I64>
372 + Into<Self::F64>;
373 type I32: SInt<Self::U32>
374 + Compare<Bool = Self::Bool>
375 + Make<Self, Prim = i32>
376 + ConvertTo<Self::U8>
377 + ConvertTo<Self::I8>
378 + ConvertTo<Self::U16>
379 + ConvertTo<Self::I16>
380 + ConvertTo<Self::F16>
381 + ConvertTo<Self::U32>
382 + ConvertTo<Self::F32>
383 + ConvertTo<Self::U64>
384 + Into<Self::I64>
385 + Into<Self::F64>;
386 type I64: SInt<Self::U32>
387 + Compare<Bool = Self::Bool>
388 + Make<Self, Prim = i64>
389 + ConvertTo<Self::U8>
390 + ConvertTo<Self::I8>
391 + ConvertTo<Self::U16>
392 + ConvertTo<Self::I16>
393 + ConvertTo<Self::F16>
394 + ConvertTo<Self::U32>
395 + ConvertTo<Self::I32>
396 + ConvertTo<Self::F32>
397 + ConvertTo<Self::U64>
398 + ConvertTo<Self::F64>;
399 type F16: Float<Self::U32, BitsType = Self::U16>
400 + Compare<Bool = Self::Bool>
401 + Make<Self, Prim = F16>
402 + ConvertTo<Self::U8>
403 + ConvertTo<Self::I8>
404 + ConvertTo<Self::U16>
405 + ConvertTo<Self::I16>
406 + ConvertTo<Self::U32>
407 + ConvertTo<Self::I32>
408 + Into<Self::F32>
409 + ConvertTo<Self::U64>
410 + ConvertTo<Self::I64>
411 + Into<Self::F64>;
412 type F32: Float<Self::U32, BitsType = Self::U32>
413 + Compare<Bool = Self::Bool>
414 + Make<Self, Prim = f32>
415 + ConvertTo<Self::U8>
416 + ConvertTo<Self::I8>
417 + ConvertTo<Self::U16>
418 + ConvertTo<Self::I16>
419 + ConvertTo<Self::F16>
420 + ConvertTo<Self::U32>
421 + ConvertTo<Self::I32>
422 + ConvertTo<Self::U64>
423 + ConvertTo<Self::I64>
424 + Into<Self::F64>;
425 type F64: Float<Self::U32, BitsType = Self::U64>
426 + Compare<Bool = Self::Bool>
427 + Make<Self, Prim = f64>
428 + ConvertTo<Self::U8>
429 + ConvertTo<Self::I8>
430 + ConvertTo<Self::U16>
431 + ConvertTo<Self::I16>
432 + ConvertTo<Self::F16>
433 + ConvertTo<Self::U32>
434 + ConvertTo<Self::I32>
435 + ConvertTo<Self::F32>
436 + ConvertTo<Self::U64>
437 + ConvertTo<Self::I64>;
438 // Vector types
439 type VecBool: From<Self::Bool> + Bool + Make<Self, Prim = bool> + Select<Self::VecBool>;
440 type VecU8: From<Self::U8>
441 + UInt<Self::VecU32>
442 + Compare<Bool = Self::VecBool>
443 + Make<Self, Prim = u8>;
444 type VecI8: From<Self::I8>
445 + SInt<Self::VecU32>
446 + Compare<Bool = Self::VecBool>
447 + Make<Self, Prim = i8>;
448 type VecU16: From<Self::U16>
449 + UInt<Self::VecU32>
450 + Compare<Bool = Self::VecBool>
451 + Make<Self, Prim = u16>;
452 type VecI16: From<Self::I16>
453 + SInt<Self::VecU32>
454 + Compare<Bool = Self::VecBool>
455 + Make<Self, Prim = i16>;
456 type VecF16: From<Self::F16> + Float + Compare<Bool = Self::VecBool> + Make<Self, Prim = F16>;
457 type VecU32: From<Self::U32>
458 + UInt<Self::VecU32>
459 + Compare<Bool = Self::VecBool>
460 + Make<Self, Prim = u32>;
461 type VecI32: From<Self::I32>
462 + SInt<Self::VecU32>
463 + Compare<Bool = Self::VecBool>
464 + Make<Self, Prim = i32>;
465 type VecF32: From<Self::F32> + Float + Compare<Bool = Self::VecBool> + Make<Self, Prim = f32>;
466 type VecU64: From<Self::U64>
467 + UInt<Self::VecU32>
468 + Compare<Bool = Self::VecBool>
469 + Make<Self, Prim = u64>;
470 type VecI64: From<Self::I64>
471 + SInt<Self::VecU32>
472 + Compare<Bool = Self::VecBool>
473 + Make<Self, Prim = i64>;
474 type VecF64: From<Self::F64> + Float + Compare<Bool = Self::VecBool> + Make<Self, Prim = f64>;
475 fn make<T: Make<Self>>(self, v: T::Prim) -> T {
476 T::make(self, v)
477 }
478 }
479
480 pub trait Make<Context>: Sized {
481 type Prim;
482 fn make(ctx: Context, v: Self::Prim) -> Self;
483 }
484
485 pub trait ConvertTo<T> {
486 fn to(self) -> T;
487 }
488
489 impl<T, U: Into<T>> ConvertTo<T> for U {
490 fn to(self) -> T {
491 self.into()
492 }
493 }
494
495 pub trait Number:
496 Compare
497 + Add<Output = Self>
498 + Sub<Output = Self>
499 + Mul<Output = Self>
500 + Div<Output = Self>
501 + Rem<Output = Self>
502 + AddAssign
503 + SubAssign
504 + MulAssign
505 + DivAssign
506 + RemAssign
507 {
508 }
509
510 pub trait BitOps:
511 Copy
512 + BitAnd<Output = Self>
513 + BitOr<Output = Self>
514 + BitXor<Output = Self>
515 + Not<Output = Self>
516 + BitAndAssign
517 + BitOrAssign
518 + BitXorAssign
519 {
520 }
521
522 pub trait Int<ShiftRhs>:
523 Number
524 + BitOps
525 + Shl<ShiftRhs, Output = Self>
526 + Shr<ShiftRhs, Output = Self>
527 + ShlAssign<ShiftRhs>
528 + ShrAssign<ShiftRhs>
529 {
530 }
531
532 pub trait UInt<ShiftRhs>: Int<ShiftRhs> {}
533
534 pub trait SInt<ShiftRhs>: Int<ShiftRhs> + Neg<Output = Self> {}
535
536 pub trait Float<BitsShiftRhs>: Number + Neg<Output = Self> {
537 type BitsType: UInt<BitsShiftRhs>;
538 fn abs(self) -> Self;
539 fn trunc(self) -> Self;
540 fn ceil(self) -> Self;
541 fn floor(self) -> Self;
542 fn round(self) -> Self;
543 fn fma(self, a: Self, b: Self) -> Self;
544 fn is_nan(self) -> Self::Bool;
545 fn is_infinity(self) -> Self::Bool;
546 fn is_finite(self) -> Self::Bool;
547 fn from_bits(v: Self::BitsType) -> Self;
548 fn to_bits(self) -> Self::BitsType;
549 }
550
551 pub trait Bool: BitOps {}
552
553 pub trait Select<T>: Bool {
554 fn select(self, true_v: T, false_v: T) -> T;
555 }
556
557 pub trait Compare: Copy {
558 type Bool: Bool + Select<Self>;
559 fn eq(self, rhs: Self) -> Self::Bool;
560 fn ne(self, rhs: Self) -> Self::Bool;
561 fn lt(self, rhs: Self) -> Self::Bool;
562 fn gt(self, rhs: Self) -> Self::Bool;
563 fn le(self, rhs: Self) -> Self::Bool;
564 fn ge(self, rhs: Self) -> Self::Bool;
565 }