Clean up BitBoard's bit ops impl macros
Declare the `forward_ref` crate as a dependency (my first external dependency!) and use it to clean up the infix, assign, and unary op impls. This crate automatically implements A+&B, &A+B, and &A+&B for me.
This commit is contained in:
parent
2480ef25e9
commit
14ab669763
2 changed files with 14 additions and 29 deletions
|
@ -7,3 +7,4 @@ edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
chessfriend_core = { path = "../core" }
|
chessfriend_core = { path = "../core" }
|
||||||
|
forward_ref = "1.0.0"
|
||||||
|
|
|
@ -3,8 +3,9 @@
|
||||||
use crate::library;
|
use crate::library;
|
||||||
use crate::{LeadingBitScanner, TrailingBitScanner};
|
use crate::{LeadingBitScanner, TrailingBitScanner};
|
||||||
use chessfriend_core::{Color, Direction, File, Rank, Square};
|
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::fmt;
|
||||||
use std::ops::Not;
|
use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Eq, Hash, PartialEq)]
|
#[derive(Clone, Copy, Eq, Hash, PartialEq)]
|
||||||
pub struct BitBoard(pub(crate) u64);
|
pub struct BitBoard(pub(crate) u64);
|
||||||
|
@ -293,61 +294,43 @@ impl fmt::Debug for BitBoard {
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! infix_op {
|
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) => {
|
($trait_type:ident, $func_name:ident, $left_type:ty, $right_type:ty) => {
|
||||||
impl std::ops::$trait_type<$right_type> for $left_type {
|
impl std::ops::$trait_type<$right_type> for $left_type {
|
||||||
type Output = BitBoard;
|
type Output = Self;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $func_name(self, rhs: $right_type) -> Self::Output {
|
fn $func_name(self, rhs: $right_type) -> Self::Output {
|
||||||
BitBoard(std::ops::$trait_type::$func_name(self.0, rhs.0))
|
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 {
|
macro_rules! assign_op {
|
||||||
($trait_type:ident, $func_name:ident, $type:ty) => {
|
($trait_type:ident, $func_name:ident, $type:ty) => {
|
||||||
impl std::ops::$trait_type for $type {
|
impl $trait_type for $type {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $func_name(&mut self, rhs: $type) {
|
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 {
|
forward_ref_op_assign!(impl $trait_type, $func_name for $type, $type);
|
||||||
#[inline]
|
|
||||||
fn $func_name(&mut self, rhs: &$type) {
|
|
||||||
std::ops::$trait_type::$func_name(&mut self.0, rhs.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
infix_op!(BitAnd, bitand, BitBoard);
|
infix_op!(BitAnd, bitand, BitBoard, BitBoard);
|
||||||
infix_op!(BitOr, bitor, BitBoard);
|
infix_op!(BitOr, bitor, BitBoard, BitBoard);
|
||||||
infix_op!(BitXor, bitxor, BitBoard);
|
infix_op!(BitXor, bitxor, BitBoard, BitBoard);
|
||||||
|
|
||||||
assign_op!(BitAndAssign, bitand_assign, BitBoard);
|
assign_op!(BitAndAssign, bitand_assign, BitBoard);
|
||||||
assign_op!(BitOrAssign, bitor_assign, BitBoard);
|
assign_op!(BitOrAssign, bitor_assign, BitBoard);
|
||||||
assign_op!(BitXorAssign, bitxor_assign, BitBoard);
|
assign_op!(BitXorAssign, bitxor_assign, BitBoard);
|
||||||
|
|
||||||
impl Not for BitBoard {
|
impl Not for BitBoard {
|
||||||
type Output = BitBoard;
|
type Output = Self;
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn not(self) -> Self::Output {
|
|
||||||
BitBoard(!self.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Not for &BitBoard {
|
|
||||||
type Output = BitBoard;
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn not(self) -> Self::Output {
|
fn not(self) -> Self::Output {
|
||||||
|
@ -355,6 +338,7 @@ impl Not for &BitBoard {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
forward_ref_unop!(impl Not, not for BitBoard);
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue