134 lines
4.0 KiB
Rust
134 lines
4.0 KiB
Rust
|
|
||
|
macro_rules! forward_val_val_binop {
|
||
|
(impl $imp:ident for $res:ty, $method:ident) => {
|
||
|
impl $imp<$res> for $res {
|
||
|
type Output = $res;
|
||
|
|
||
|
#[inline]
|
||
|
fn $method(self, other: $res) -> $res {
|
||
|
// forward to val-ref
|
||
|
$imp::$method(self, &other)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
macro_rules! forward_val_val_binop_commutative {
|
||
|
(impl $imp:ident for $res:ty, $method:ident) => {
|
||
|
impl $imp<$res> for $res {
|
||
|
type Output = $res;
|
||
|
|
||
|
#[inline]
|
||
|
fn $method(self, other: $res) -> $res {
|
||
|
// forward to val-ref, with the larger capacity as val
|
||
|
if self.data.capacity() >= other.data.capacity() {
|
||
|
$imp::$method(self, &other)
|
||
|
} else {
|
||
|
$imp::$method(other, &self)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
macro_rules! forward_ref_val_binop {
|
||
|
(impl $imp:ident for $res:ty, $method:ident) => {
|
||
|
impl<'a> $imp<$res> for &'a $res {
|
||
|
type Output = $res;
|
||
|
|
||
|
#[inline]
|
||
|
fn $method(self, other: $res) -> $res {
|
||
|
// forward to ref-ref
|
||
|
$imp::$method(self, &other)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
macro_rules! forward_ref_val_binop_commutative {
|
||
|
(impl $imp:ident for $res:ty, $method:ident) => {
|
||
|
impl<'a> $imp<$res> for &'a $res {
|
||
|
type Output = $res;
|
||
|
|
||
|
#[inline]
|
||
|
fn $method(self, other: $res) -> $res {
|
||
|
// reverse, forward to val-ref
|
||
|
$imp::$method(other, self)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
macro_rules! forward_val_ref_binop {
|
||
|
(impl $imp:ident for $res:ty, $method:ident) => {
|
||
|
impl<'a> $imp<&'a $res> for $res {
|
||
|
type Output = $res;
|
||
|
|
||
|
#[inline]
|
||
|
fn $method(self, other: &$res) -> $res {
|
||
|
// forward to ref-ref
|
||
|
$imp::$method(&self, other)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
macro_rules! forward_ref_ref_binop {
|
||
|
(impl $imp:ident for $res:ty, $method:ident) => {
|
||
|
impl<'a, 'b> $imp<&'b $res> for &'a $res {
|
||
|
type Output = $res;
|
||
|
|
||
|
#[inline]
|
||
|
fn $method(self, other: &$res) -> $res {
|
||
|
// forward to val-ref
|
||
|
$imp::$method(self.clone(), other)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
macro_rules! forward_ref_ref_binop_commutative {
|
||
|
(impl $imp:ident for $res:ty, $method:ident) => {
|
||
|
impl<'a, 'b> $imp<&'b $res> for &'a $res {
|
||
|
type Output = $res;
|
||
|
|
||
|
#[inline]
|
||
|
fn $method(self, other: &$res) -> $res {
|
||
|
// forward to val-ref, choosing the larger to clone
|
||
|
if self.data.len() >= other.data.len() {
|
||
|
$imp::$method(self.clone(), other)
|
||
|
} else {
|
||
|
$imp::$method(other.clone(), self)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Forward everything to ref-ref, when reusing storage is not helpful
|
||
|
macro_rules! forward_all_binop_to_ref_ref {
|
||
|
(impl $imp:ident for $res:ty, $method:ident) => {
|
||
|
forward_val_val_binop!(impl $imp for $res, $method);
|
||
|
forward_val_ref_binop!(impl $imp for $res, $method);
|
||
|
forward_ref_val_binop!(impl $imp for $res, $method);
|
||
|
};
|
||
|
}
|
||
|
|
||
|
// Forward everything to val-ref, so LHS storage can be reused
|
||
|
macro_rules! forward_all_binop_to_val_ref {
|
||
|
(impl $imp:ident for $res:ty, $method:ident) => {
|
||
|
forward_val_val_binop!(impl $imp for $res, $method);
|
||
|
forward_ref_val_binop!(impl $imp for $res, $method);
|
||
|
forward_ref_ref_binop!(impl $imp for $res, $method);
|
||
|
};
|
||
|
}
|
||
|
|
||
|
// Forward everything to val-ref, commutatively, so either LHS or RHS storage can be reused
|
||
|
macro_rules! forward_all_binop_to_val_ref_commutative {
|
||
|
(impl $imp:ident for $res:ty, $method:ident) => {
|
||
|
forward_val_val_binop_commutative!(impl $imp for $res, $method);
|
||
|
forward_ref_val_binop_commutative!(impl $imp for $res, $method);
|
||
|
forward_ref_ref_binop_commutative!(impl $imp for $res, $method);
|
||
|
};
|
||
|
}
|