use crate::macros::for_all_ints;
use crate::ops::bit::impls::BitwiseOp;
use crate::util::IntoArbiLikeArray;
use crate::Arbi;
use core::ops::{
BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign,
};
macro_rules! impl_bit_with_int {
($($int:ty),*) => {
$(
impl BitAndAssign<$int> for Arbi {
fn bitand_assign(&mut self, rhs: $int) {
let rhs = rhs.into_arbi_like_array();
self.inplace_bitwise_op_with_arbi_like_view((&rhs).into(), BitwiseOp::And);
}
}
impl BitOrAssign<$int> for Arbi {
fn bitor_assign(&mut self, rhs: $int) {
let rhs = rhs.into_arbi_like_array();
self.inplace_bitwise_op_with_arbi_like_view((&rhs).into(), BitwiseOp::Ior);
}
}
impl BitXorAssign<$int> for Arbi {
fn bitxor_assign(&mut self, rhs: $int) {
let rhs = rhs.into_arbi_like_array();
self.inplace_bitwise_op_with_arbi_like_view((&rhs).into(), BitwiseOp::Xor);
}
}
impl BitAnd<$int> for Arbi {
type Output = Arbi;
fn bitand(mut self, rhs: $int) -> Arbi {
self &= rhs;
self
}
}
impl BitOr<$int> for Arbi {
type Output = Arbi;
fn bitor(mut self, rhs: $int) -> Arbi {
self |= rhs;
self
}
}
impl BitXor<$int> for Arbi {
type Output = Arbi;
fn bitxor(mut self, rhs: $int) -> Arbi {
self ^= rhs;
self
}
}
impl BitAnd<Arbi> for $int {
type Output = Arbi;
fn bitand(self, mut rhs: Arbi) -> Arbi {
rhs &= self;
rhs
}
}
impl BitOr<Arbi> for $int {
type Output = Arbi;
fn bitor(self, mut rhs: Arbi) -> Arbi {
rhs |= self;
rhs
}
}
impl BitXor<Arbi> for $int {
type Output = Arbi;
fn bitxor(self, mut rhs: Arbi) -> Arbi {
rhs ^= self;
rhs
}
}
impl BitAnd<$int> for &Arbi {
type Output = Arbi;
fn bitand(self, rhs: $int) -> Arbi {
self.clone() & rhs
}
}
impl BitOr<$int> for &Arbi {
type Output = Arbi;
fn bitor(self, rhs: $int) -> Arbi {
self.clone() | rhs
}
}
impl BitXor<$int> for &Arbi {
type Output = Arbi;
fn bitxor(self, rhs: $int) -> Arbi {
self.clone() ^ rhs
}
}
impl BitAnd<&Arbi> for $int {
type Output = Arbi;
fn bitand(self, rhs: &Arbi) -> Arbi {
rhs & self
}
}
impl BitOr<&Arbi> for $int {
type Output = Arbi;
fn bitor(self, rhs: &Arbi) -> Arbi {
rhs | self
}
}
impl BitXor<&Arbi> for $int {
type Output = Arbi;
fn bitxor(self, rhs: &Arbi) -> Arbi {
rhs ^ self
}
}
)*
};
}
for_all_ints!(impl_bit_with_int);
macro_rules! impl_bit_with_int_ref {
($($int:ty),*) => {
$(
impl BitAndAssign<&$int> for Arbi {
fn bitand_assign(&mut self, rhs: &$int) {
(*self) &= (*rhs);
}
}
impl BitOrAssign<&$int> for Arbi {
fn bitor_assign(&mut self, rhs: &$int) {
(*self) |= (*rhs);
}
}
impl BitXorAssign<&$int> for Arbi {
fn bitxor_assign(&mut self, rhs: &$int) {
(*self) ^= (*rhs);
}
}
impl BitAnd<&$int> for Arbi {
type Output = Arbi;
fn bitand(self, rhs: &$int) -> Arbi {
self & (*rhs)
}
}
impl BitOr<&$int> for Arbi {
type Output = Arbi;
fn bitor(self, rhs: &$int) -> Arbi {
self | (*rhs)
}
}
impl BitXor<&$int> for Arbi {
type Output = Arbi;
fn bitxor(self, rhs: &$int) -> Arbi {
self ^ (*rhs)
}
}
impl BitAnd<Arbi> for &$int {
type Output = Arbi;
fn bitand(self, rhs: Arbi) -> Arbi {
(*self) & rhs
}
}
impl BitOr<Arbi> for &$int {
type Output = Arbi;
fn bitor(self, rhs: Arbi) -> Arbi {
(*self) | rhs
}
}
impl BitXor<Arbi> for &$int {
type Output = Arbi;
fn bitxor(self, rhs: Arbi) -> Arbi {
(*self) ^ rhs
}
}
impl BitAnd<&$int> for &Arbi {
type Output = Arbi;
fn bitand(self, rhs: &$int) -> Arbi {
self & (*rhs)
}
}
impl BitOr<&$int> for &Arbi {
type Output = Arbi;
fn bitor(self, rhs: &$int) -> Arbi {
self | (*rhs)
}
}
impl BitXor<&$int> for &Arbi {
type Output = Arbi;
fn bitxor(self, rhs: &$int) -> Arbi {
self ^ (*rhs)
}
}
impl BitAnd<&Arbi> for &$int {
type Output = Arbi;
fn bitand(self, rhs: &Arbi) -> Arbi {
(*self) & rhs
}
}
impl BitOr<&Arbi> for &$int {
type Output = Arbi;
fn bitor(self, rhs: &Arbi) -> Arbi {
(*self) | rhs
}
}
impl BitXor<&Arbi> for &$int {
type Output = Arbi;
fn bitxor(self, rhs: &Arbi) -> Arbi {
(*self) ^ rhs
}
}
)*
};
}
for_all_ints!(impl_bit_with_int_ref);