diff --git a/bitboard/Cargo.toml b/bitboard/Cargo.toml index df608b5..26df504 100644 --- a/bitboard/Cargo.toml +++ b/bitboard/Cargo.toml @@ -7,3 +7,4 @@ edition = "2021" [dependencies] chessfriend_core = { path = "../core" } +forward_ref = "1.0.0" diff --git a/bitboard/src/bitboard.rs b/bitboard/src/bitboard.rs index 205b13a..6adc05c 100644 --- a/bitboard/src/bitboard.rs +++ b/bitboard/src/bitboard.rs @@ -3,8 +3,9 @@ use crate::library; use crate::{LeadingBitScanner, TrailingBitScanner}; use chessfriend_core::{Color, Direction, File, Rank, Square}; +use forward_ref::{forward_ref_binop, forward_ref_op_assign, forward_ref_unop}; use std::fmt; -use std::ops::Not; +use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not}; #[derive(Clone, Copy, Eq, Hash, PartialEq)] pub struct BitBoard(pub(crate) u64); @@ -293,61 +294,43 @@ impl fmt::Debug for BitBoard { } macro_rules! infix_op { - ($trait_type:ident, $func_name:ident, $type:ty) => { - infix_op!($trait_type, $func_name, $type, $type); - infix_op!($trait_type, $func_name, $type, &$type); - infix_op!($trait_type, $func_name, &$type, $type); - infix_op!($trait_type, $func_name, &$type, &$type); - }; ($trait_type:ident, $func_name:ident, $left_type:ty, $right_type:ty) => { impl std::ops::$trait_type<$right_type> for $left_type { - type Output = BitBoard; + type Output = Self; #[inline] fn $func_name(self, rhs: $right_type) -> Self::Output { BitBoard(std::ops::$trait_type::$func_name(self.0, rhs.0)) } } + + forward_ref_binop!(impl $trait_type, $func_name for $left_type, $right_type); }; } macro_rules! assign_op { ($trait_type:ident, $func_name:ident, $type:ty) => { - impl std::ops::$trait_type for $type { + impl $trait_type for $type { #[inline] fn $func_name(&mut self, rhs: $type) { - std::ops::$trait_type::$func_name(&mut self.0, rhs.0) + $trait_type::$func_name(&mut self.0, rhs.0) } } - impl std::ops::$trait_type<&$type> for $type { - #[inline] - fn $func_name(&mut self, rhs: &$type) { - std::ops::$trait_type::$func_name(&mut self.0, rhs.0) - } - } + forward_ref_op_assign!(impl $trait_type, $func_name for $type, $type); }; } -infix_op!(BitAnd, bitand, BitBoard); -infix_op!(BitOr, bitor, BitBoard); -infix_op!(BitXor, bitxor, BitBoard); +infix_op!(BitAnd, bitand, BitBoard, BitBoard); +infix_op!(BitOr, bitor, BitBoard, BitBoard); +infix_op!(BitXor, bitxor, BitBoard, BitBoard); assign_op!(BitAndAssign, bitand_assign, BitBoard); assign_op!(BitOrAssign, bitor_assign, BitBoard); assign_op!(BitXorAssign, bitxor_assign, BitBoard); impl Not for BitBoard { - type Output = BitBoard; - - #[inline] - fn not(self) -> Self::Output { - BitBoard(!self.0) - } -} - -impl Not for &BitBoard { - type Output = BitBoard; + type Output = Self; #[inline] fn not(self) -> Self::Output { @@ -355,6 +338,7 @@ impl Not for &BitBoard { } } +forward_ref_unop!(impl Not, not for BitBoard); #[cfg(test)] mod tests {