1use core::ops::{BitAnd, BitOr, BitXor, Not};
2
3use paste::paste;
4
5use crate::{Scalar, Simd, Vector};
6
7macro_rules! impl_bitwise {
8 ($trait: ident, $std_trait: path, $name: ident) => {
9 paste!{
10 pub trait $trait: Scalar + $std_trait<Output = Self> {
11 fn [<$trait:lower>]<S: Simd>(lhs: Vector<S, Self>, rhs: Vector<S, Self>) -> Vector<S, Self> {
12 S::typed(S::$name(*lhs, *rhs))
13 }
14 fn is_accelerated<S: Simd>() -> bool {
15 S::[<$name _supported>]()
16 }
17 }
18 impl<T: $std_trait<Output = Self> + Scalar> $trait for T {}
19 impl<S: Simd, T: $trait> $std_trait<Self> for Vector<S, T> {
20 type Output = Self;
21
22 #[inline(always)]
23 fn $name(self, rhs: Self) -> Self::Output {
24 T::[<$trait:lower>](self, rhs)
25 }
26 }
27 impl<S: Simd, T: $trait> ::core::ops::[<$std_trait Assign>]<Self> for Vector<S, T> {
28 #[inline(always)]
29 fn [<$name _assign>](&mut self, rhs: Self) {
30 *self = T::[<$trait:lower>](*self, rhs)
31 }
32 }
33 }
34 };
35}
36
37impl_bitwise!(VBitAnd, BitAnd, bitand);
38impl_bitwise!(VBitOr, BitOr, bitor);
39impl_bitwise!(VBitXor, BitXor, bitxor);
40
41macro_rules! impl_bitwise_unary {
42 ($trait: ident, $std_trait: path, $name: ident) => {
43 paste! {
44 pub trait $trait: Scalar + $std_trait<Output = Self> {
45 #[inline(always)]
46 fn [<$trait:lower>]<S: Simd>(a: Vector<S, Self>) -> Vector<S, Self> {
47 S::typed(S::$name(*a))
48 }
49 #[inline(always)]
50 fn is_accelerated<S: Simd>() -> bool {
51 S::[<$name _supported>]()
52 }
53 }
54 impl<T: $std_trait<Output = Self> + Scalar> $trait for T {}
55 impl<S: Simd, T: $trait> $std_trait for Vector<S, T> {
56 type Output = Self;
57
58 #[inline(always)]
59 fn [<$std_trait:lower>](self) -> Self::Output {
60 T::[<$trait:lower>](self)
61 }
62 }
63 }
64 };
65}
66
67impl_bitwise_unary!(VBitNot, Not, bitnot);