add sin_pi_f16, cos_pi_f16, and sin_cos_pi_f16
[vector-math.git] / src / scalar.rs
1 use crate::{
2 f16::F16,
3 traits::{Bool, Compare, Context, ConvertFrom, Float, Int, Make, SInt, Select, UInt},
4 };
5 use core::ops::{
6 Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign,
7 Mul, MulAssign, Neg, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign,
8 };
9
10 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default)]
11 pub struct Scalar;
12
13 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default)]
14 #[repr(transparent)]
15 pub struct Value<T>(pub T);
16
17 macro_rules! impl_convert_from {
18 ($first:ident $(, $ty:ident)*) => {
19 $(
20 impl ConvertFrom<Value<$first>> for Value<$ty> {
21 fn cvt_from(v: Value<$first>) -> Self {
22 Value(ConvertFrom::cvt_from(v.0))
23 }
24 }
25 impl ConvertFrom<Value<$ty>> for Value<$first> {
26 fn cvt_from(v: Value<$ty>) -> Self {
27 Value(ConvertFrom::cvt_from(v.0))
28 }
29 }
30 )*
31 impl_convert_from![$($ty),*];
32 };
33 () => {
34 };
35 }
36
37 impl_convert_from![u8, i8, u16, i16, F16, u32, i32, u64, i64, f32, f64];
38
39 macro_rules! impl_bit_ops {
40 ($ty:ident) => {
41 impl BitAnd for Value<$ty> {
42 type Output = Self;
43
44 fn bitand(self, rhs: Self) -> Self {
45 Value(self.0 & rhs.0)
46 }
47 }
48
49 impl BitOr for Value<$ty> {
50 type Output = Self;
51
52 fn bitor(self, rhs: Self) -> Self {
53 Value(self.0 | rhs.0)
54 }
55 }
56
57 impl BitXor for Value<$ty> {
58 type Output = Self;
59
60 fn bitxor(self, rhs: Self) -> Self {
61 Value(self.0 ^ rhs.0)
62 }
63 }
64
65 impl Not for Value<$ty> {
66 type Output = Self;
67
68 fn not(self) -> Self {
69 Value(!self.0)
70 }
71 }
72
73 impl BitAndAssign for Value<$ty> {
74 fn bitand_assign(&mut self, rhs: Self) {
75 self.0 &= rhs.0;
76 }
77 }
78
79 impl BitOrAssign for Value<$ty> {
80 fn bitor_assign(&mut self, rhs: Self) {
81 self.0 |= rhs.0;
82 }
83 }
84
85 impl BitXorAssign for Value<$ty> {
86 fn bitxor_assign(&mut self, rhs: Self) {
87 self.0 ^= rhs.0;
88 }
89 }
90 };
91 }
92
93 macro_rules! impl_wrapping_int_ops {
94 ($ty:ident) => {
95 impl Add for Value<$ty> {
96 type Output = Self;
97
98 fn add(self, rhs: Self) -> Self {
99 Value(self.0.wrapping_add(rhs.0))
100 }
101 }
102
103 impl Sub for Value<$ty> {
104 type Output = Self;
105
106 fn sub(self, rhs: Self) -> Self {
107 Value(self.0.wrapping_sub(rhs.0))
108 }
109 }
110
111 impl Mul for Value<$ty> {
112 type Output = Self;
113
114 fn mul(self, rhs: Self) -> Self {
115 Value(self.0.wrapping_mul(rhs.0))
116 }
117 }
118
119 impl Div for Value<$ty> {
120 type Output = Self;
121
122 fn div(self, rhs: Self) -> Self {
123 Value(self.0.wrapping_div(rhs.0))
124 }
125 }
126
127 impl Rem for Value<$ty> {
128 type Output = Self;
129
130 fn rem(self, rhs: Self) -> Self {
131 Value(self.0.wrapping_rem(rhs.0))
132 }
133 }
134
135 impl Shl for Value<$ty> {
136 type Output = Self;
137
138 fn shl(self, rhs: Self) -> Self {
139 Value(self.0.wrapping_shl(rhs.0 as u32))
140 }
141 }
142
143 impl Shr for Value<$ty> {
144 type Output = Self;
145
146 fn shr(self, rhs: Self) -> Self {
147 Value(self.0.wrapping_shr(rhs.0 as u32))
148 }
149 }
150
151 impl Neg for Value<$ty> {
152 type Output = Self;
153
154 fn neg(self) -> Self {
155 Value(self.0.wrapping_neg())
156 }
157 }
158
159 impl AddAssign for Value<$ty> {
160 fn add_assign(&mut self, rhs: Self) {
161 *self = self.add(rhs);
162 }
163 }
164
165 impl SubAssign for Value<$ty> {
166 fn sub_assign(&mut self, rhs: Self) {
167 *self = self.sub(rhs);
168 }
169 }
170
171 impl MulAssign for Value<$ty> {
172 fn mul_assign(&mut self, rhs: Self) {
173 *self = self.mul(rhs);
174 }
175 }
176
177 impl DivAssign for Value<$ty> {
178 fn div_assign(&mut self, rhs: Self) {
179 *self = self.div(rhs);
180 }
181 }
182
183 impl RemAssign for Value<$ty> {
184 fn rem_assign(&mut self, rhs: Self) {
185 *self = self.rem(rhs);
186 }
187 }
188
189 impl ShlAssign for Value<$ty> {
190 fn shl_assign(&mut self, rhs: Self) {
191 *self = self.shl(rhs);
192 }
193 }
194
195 impl ShrAssign for Value<$ty> {
196 fn shr_assign(&mut self, rhs: Self) {
197 *self = self.shr(rhs);
198 }
199 }
200 };
201 }
202 macro_rules! impl_int {
203 ($ty:ident) => {
204 impl_bit_ops!($ty);
205 impl_wrapping_int_ops!($ty);
206 impl Int for Value<$ty> {
207 fn leading_zeros(self) -> Self {
208 Value(self.0.leading_zeros() as $ty)
209 }
210 fn leading_ones(self) -> Self {
211 Value(self.0.leading_ones() as $ty)
212 }
213 fn trailing_zeros(self) -> Self {
214 Value(self.0.trailing_zeros() as $ty)
215 }
216 fn trailing_ones(self) -> Self {
217 Value(self.0.trailing_ones() as $ty)
218 }
219 fn count_zeros(self) -> Self {
220 Value(self.0.count_zeros() as $ty)
221 }
222 fn count_ones(self) -> Self {
223 Value(self.0.count_ones() as $ty)
224 }
225 }
226 };
227 }
228
229 macro_rules! impl_uint {
230 ($($ty:ident),*) => {
231 $(
232 impl_int!($ty);
233 impl UInt for Value<$ty> {}
234 )*
235 };
236 }
237
238 impl_uint![u8, u16, u32, u64];
239
240 macro_rules! impl_sint {
241 ($($ty:ident),*) => {
242 $(
243 impl_int!($ty);
244 impl SInt for Value<$ty> {}
245 )*
246 };
247 }
248
249 impl_sint![i8, i16, i32, i64];
250
251 macro_rules! impl_float_ops {
252 ($ty:ident) => {
253 impl Add for Value<$ty> {
254 type Output = Self;
255
256 fn add(self, rhs: Self) -> Self {
257 Value(self.0.add(rhs.0))
258 }
259 }
260
261 impl Sub for Value<$ty> {
262 type Output = Self;
263
264 fn sub(self, rhs: Self) -> Self {
265 Value(self.0.sub(rhs.0))
266 }
267 }
268
269 impl Mul for Value<$ty> {
270 type Output = Self;
271
272 fn mul(self, rhs: Self) -> Self {
273 Value(self.0.mul(rhs.0))
274 }
275 }
276
277 impl Div for Value<$ty> {
278 type Output = Self;
279
280 fn div(self, rhs: Self) -> Self {
281 Value(self.0.div(rhs.0))
282 }
283 }
284
285 impl Rem for Value<$ty> {
286 type Output = Self;
287
288 fn rem(self, rhs: Self) -> Self {
289 Value(self.0.rem(rhs.0))
290 }
291 }
292
293 impl Neg for Value<$ty> {
294 type Output = Self;
295
296 fn neg(self) -> Self {
297 Value(self.0.neg())
298 }
299 }
300
301 impl AddAssign for Value<$ty> {
302 fn add_assign(&mut self, rhs: Self) {
303 *self = self.add(rhs);
304 }
305 }
306
307 impl SubAssign for Value<$ty> {
308 fn sub_assign(&mut self, rhs: Self) {
309 *self = self.sub(rhs);
310 }
311 }
312
313 impl MulAssign for Value<$ty> {
314 fn mul_assign(&mut self, rhs: Self) {
315 *self = self.mul(rhs);
316 }
317 }
318
319 impl DivAssign for Value<$ty> {
320 fn div_assign(&mut self, rhs: Self) {
321 *self = self.div(rhs);
322 }
323 }
324
325 impl RemAssign for Value<$ty> {
326 fn rem_assign(&mut self, rhs: Self) {
327 *self = self.rem(rhs);
328 }
329 }
330 };
331 }
332
333 impl_float_ops!(F16);
334
335 macro_rules! impl_float {
336 ($ty:ident, $bits:ty, $signed_bits:ty) => {
337 impl_float_ops!($ty);
338 impl Float for Value<$ty> {
339 type FloatEncoding = $ty;
340 type BitsType = Value<$bits>;
341 type SignedBitsType = Value<$signed_bits>;
342 fn abs(self) -> Self {
343 #[cfg(feature = "std")]
344 return Value(self.0.abs());
345 #[cfg(not(feature = "std"))]
346 todo!();
347 }
348 fn trunc(self) -> Self {
349 #[cfg(feature = "std")]
350 return Value(self.0.trunc());
351 #[cfg(not(feature = "std"))]
352 todo!();
353 }
354 fn ceil(self) -> Self {
355 #[cfg(feature = "std")]
356 return Value(self.0.ceil());
357 #[cfg(not(feature = "std"))]
358 todo!();
359 }
360 fn floor(self) -> Self {
361 #[cfg(feature = "std")]
362 return Value(self.0.floor());
363 #[cfg(not(feature = "std"))]
364 todo!();
365 }
366 fn round(self) -> Self {
367 #[cfg(feature = "std")]
368 return Value(self.0.round());
369 #[cfg(not(feature = "std"))]
370 todo!();
371 }
372 #[cfg(feature = "fma")]
373 fn fma(self, a: Self, b: Self) -> Self {
374 Value(self.0.mul_add(a.0, b.0))
375 }
376 fn is_nan(self) -> Self::Bool {
377 Value(self.0.is_nan())
378 }
379 fn is_infinite(self) -> Self::Bool {
380 Value(self.0.is_infinite())
381 }
382 fn is_finite(self) -> Self::Bool {
383 Value(self.0.is_finite())
384 }
385 fn from_bits(v: Self::BitsType) -> Self {
386 Value(<$ty>::from_bits(v.0))
387 }
388 fn to_bits(self) -> Self::BitsType {
389 Value(self.0.to_bits())
390 }
391 }
392 };
393 }
394
395 impl_float!(f32, u32, i32);
396 impl_float!(f64, u64, i64);
397
398 macro_rules! impl_compare_using_partial_cmp {
399 ($($ty:ty),*) => {
400 $(
401 impl Compare for Value<$ty> {
402 type Bool = Value<bool>;
403 fn eq(self, rhs: Self) -> Self::Bool {
404 Value(self == rhs)
405 }
406 fn ne(self, rhs: Self) -> Self::Bool {
407 Value(self != rhs)
408 }
409 fn lt(self, rhs: Self) -> Self::Bool {
410 Value(self < rhs)
411 }
412 fn gt(self, rhs: Self) -> Self::Bool {
413 Value(self > rhs)
414 }
415 fn le(self, rhs: Self) -> Self::Bool {
416 Value(self <= rhs)
417 }
418 fn ge(self, rhs: Self) -> Self::Bool {
419 Value(self >= rhs)
420 }
421 }
422 )*
423 };
424 }
425
426 impl_compare_using_partial_cmp![bool, u8, i8, u16, i16, F16, u32, i32, f32, u64, i64, f64];
427
428 impl Bool for Value<bool> {}
429
430 impl_bit_ops!(bool);
431
432 impl<T> Select<Value<T>> for Value<bool> {
433 fn select(self, true_v: Value<T>, false_v: Value<T>) -> Value<T> {
434 if self.0 {
435 true_v
436 } else {
437 false_v
438 }
439 }
440 }
441
442 macro_rules! impl_from {
443 ($src:ident => [$($dest:ident),*]) => {
444 $(
445 impl From<Value<$src>> for Value<$dest> {
446 fn from(v: Value<$src>) -> Self {
447 Value(v.0.into())
448 }
449 }
450 )*
451 };
452 }
453
454 impl_from!(u8 => [u16, i16, F16, u32, i32, f32, u64, i64, f64]);
455 impl_from!(u16 => [u32, i32, f32, u64, i64, f64]);
456 impl_from!(u32 => [u64, i64, f64]);
457 impl_from!(i8 => [i16, F16, i32, f32, i64, f64]);
458 impl_from!(i16 => [i32, f32, i64, f64]);
459 impl_from!(i32 => [i64, f64]);
460 impl_from!(F16 => [f32, f64]);
461 impl_from!(f32 => [f64]);
462
463 macro_rules! impl_context {
464 (
465 impl Context for Scalar {
466 $(type $name:ident = Value<$ty:ident>;)*
467 #[vec]
468 $(type $vec_name:ident = Value<$vec_ty:ident>;)*
469 }
470 ) => {
471 impl Context for Scalar {
472 $(type $name = Value<$ty>;)*
473 $(type $vec_name = Value<$vec_ty>;)*
474 }
475
476 $(
477 impl Make for Value<$ty> {
478 type Prim = $ty;
479 type Context = Scalar;
480 fn ctx(self) -> Self::Context {
481 Scalar
482 }
483 fn make(_ctx: Self::Context, v: Self::Prim) -> Self {
484 Value(v)
485 }
486 }
487 )*
488 };
489 }
490
491 impl_context! {
492 impl Context for Scalar {
493 type Bool = Value<bool>;
494 type U8 = Value<u8>;
495 type I8 = Value<i8>;
496 type U16 = Value<u16>;
497 type I16 = Value<i16>;
498 type F16 = Value<F16>;
499 type U32 = Value<u32>;
500 type I32 = Value<i32>;
501 type F32 = Value<f32>;
502 type U64 = Value<u64>;
503 type I64 = Value<i64>;
504 type F64 = Value<f64>;
505 #[vec]
506 type VecBool8 = Value<bool>;
507 type VecU8 = Value<u8>;
508 type VecI8 = Value<i8>;
509 type VecBool16 = Value<bool>;
510 type VecU16 = Value<u16>;
511 type VecI16 = Value<i16>;
512 type VecF16 = Value<F16>;
513 type VecBool32 = Value<bool>;
514 type VecU32 = Value<u32>;
515 type VecI32 = Value<i32>;
516 type VecF32 = Value<f32>;
517 type VecBool64 = Value<bool>;
518 type VecU64 = Value<u64>;
519 type VecI64 = Value<i64>;
520 type VecF64 = Value<f64>;
521 }
522 }