#![cfg_attr(docsrs, feature(doc_cfg))]
use std::fmt::Debug;
use std::ops::{Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign};
use std::ops::{Div, Rem};
use std::ops::{Mul, MulAssign, Neg, Not, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign};
use generic_array::typenum::*;
use generic_array::*;
use super::*;
use crate::VarLit;
use crate::{impl_int_ipty, impl_int_upty};
impl<T, N: ArrayLength> IntVar<T, N, true>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
{
pub fn abs(&self) -> IntVar<T, N, false> {
IntVar::<T, N, false>(self.0.clone().abs())
}
}
impl<T, N, const SIGN: bool> Not for IntVar<T, N, SIGN>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
{
type Output = Self;
fn not(self) -> Self {
Self(!self.0)
}
}
impl<T, N, const SIGN: bool> Not for &IntVar<T, N, SIGN>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
{
type Output = <IntVar<T, N, SIGN> as Not>::Output;
fn not(self) -> Self::Output {
IntVar(!self.0.clone())
}
}
impl<T, N> IntModNeg for IntVar<T, N, false>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
{
type Output = Self;
fn mod_neg(self) -> Self {
Self((self.0.as_signed().mod_neg()).as_unsigned())
}
}
impl<T, N> IntModNeg for &IntVar<T, N, false>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
{
type Output = <IntVar<T, N, false> as IntModNeg>::Output;
fn mod_neg(self) -> Self::Output {
IntVar((self.0.clone().as_signed().mod_neg()).as_unsigned())
}
}
impl<T, N> IntModNeg for IntVar<T, N, true>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
{
type Output = Self;
fn mod_neg(self) -> Self {
Self(self.0.mod_neg())
}
}
impl<T, N> IntModNeg for &IntVar<T, N, true>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
{
type Output = <IntVar<T, N, true> as IntModNeg>::Output;
fn mod_neg(self) -> Self::Output {
IntVar(self.0.clone().mod_neg())
}
}
impl<T, N> Neg for IntVar<T, N, false>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
{
type Output = Self;
fn neg(self) -> Self {
Self((self.0.as_signed().mod_neg()).as_unsigned())
}
}
impl<T, N> Neg for &IntVar<T, N, false>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
{
type Output = <IntVar<T, N, false> as Neg>::Output;
fn neg(self) -> Self::Output {
IntVar((self.0.clone().as_signed().mod_neg()).as_unsigned())
}
}
impl<T, N> Neg for IntVar<T, N, true>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
{
type Output = Self;
fn neg(self) -> Self {
Self(self.0.mod_neg())
}
}
impl<T, N> Neg for &IntVar<T, N, true>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
{
type Output = <IntVar<T, N, true> as Neg>::Output;
fn neg(self) -> Self::Output {
IntVar(self.0.clone().mod_neg())
}
}
impl<T, N> IntCondNeg for IntVar<T, N, true>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
{
type Output = Self;
type OutputCond = BoolVar<T>;
fn cond_neg(self) -> (Self::Output, Self::OutputCond) {
let (r, c) = self.0.cond_neg();
(Self(r), c.into())
}
}
impl<T, N> IntCondNeg for &IntVar<T, N, true>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
{
type Output = <IntVar<T, N, true> as IntCondNeg>::Output;
type OutputCond = <IntVar<T, N, true> as IntCondNeg>::OutputCond;
fn cond_neg(self) -> (Self::Output, Self::OutputCond) {
let (r, c) = self.0.clone().cond_neg();
(IntVar(r), c.into())
}
}
impl<T, N: ArrayLength, const SIGN: bool> IntVar<T, N, SIGN>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
{
pub fn addc_with_carry(&self, rhs: &Self, in_carry: &BoolVar<T>) -> (Self, BoolVar<T>) {
let (s, c) = self
.0
.clone()
.addc_with_carry(rhs.0.clone(), in_carry.clone().into());
(Self(s), c.into())
}
pub fn addc(&self, rhs: &Self, in_carry: &BoolVar<T>) -> Self {
Self(self.0.clone().addc(rhs.0.clone(), in_carry.clone().into()))
}
pub fn subc(&self, rhs: &Self, in_carry: &BoolVar<T>) -> Self {
Self(self.0.clone().subc(rhs.0.clone(), in_carry.clone().into()))
}
pub fn add_same_carry(&self, in_carry: &BoolVar<T>) -> Self {
Self(self.0.clone().add_same_carry(in_carry.clone().into()))
}
pub fn addc_with_carry_c<BT: Into<BoolVar<T>>>(
&self,
rhs: Self,
in_carry: BT,
) -> (Self, BoolVar<T>) {
let (s, c) = self
.0
.clone()
.addc_with_carry(rhs.0.clone(), in_carry.into().into());
(Self(s), c.into())
}
pub fn addc_c<BT: Into<BoolVar<T>>>(&self, rhs: Self, in_carry: BT) -> Self {
Self(self.0.clone().addc(rhs.0.clone(), in_carry.into().into()))
}
pub fn subc_c<BT: Into<BoolVar<T>>>(&self, rhs: Self, in_carry: BT) -> Self {
Self(self.0.clone().subc(rhs.0.clone(), in_carry.into().into()))
}
pub fn add_same_carry_c<BT: Into<BoolVar<T>>>(&self, in_carry: BT) -> Self {
Self(self.0.clone().add_same_carry(in_carry.into().into()))
}
}
macro_rules! new_op_impl {
($t:ident, $u:ident, $v:ident, $macro_gen:ident, $macro_upty:ident, $macro_ipty:ident) => {
impl<T, N: ArrayLength, const SIGN: bool> $t<IntVar<T, N, SIGN>> for IntVar<T, N, SIGN>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
{
type Output = IntVar<T, N, SIGN>;
fn $u(self, rhs: IntVar<T, N, SIGN>) -> Self::Output {
Self(self.0.$v(rhs.0))
}
}
impl<T, N: ArrayLength, const SIGN: bool> $t<&IntVar<T, N, SIGN>> for IntVar<T, N, SIGN>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
{
type Output = IntVar<T, N, SIGN>;
fn $u(self, rhs: &IntVar<T, N, SIGN>) -> Self::Output {
Self(self.0.$v(rhs.0.clone()))
}
}
impl<T, N: ArrayLength, const SIGN: bool> $t<IntVar<T, N, SIGN>> for &IntVar<T, N, SIGN>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
{
type Output = IntVar<T, N, SIGN>;
fn $u(self, rhs: IntVar<T, N, SIGN>) -> Self::Output {
IntVar::<T, N, SIGN>(self.0.clone().$v(rhs.0))
}
}
impl<T, N: ArrayLength, const SIGN: bool> $t<&IntVar<T, N, SIGN>> for &IntVar<T, N, SIGN>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
{
type Output = IntVar<T, N, SIGN>;
fn $u(self, rhs: &IntVar<T, N, SIGN>) -> Self::Output {
IntVar::<T, N, SIGN>(self.0.clone().$v(rhs.0.clone()))
}
}
macro_rules! $macro_gen {
($sign:expr, $pty:ty) => {
impl<T, N: ArrayLength> $t<$pty> for IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, N, $sign>;
fn $u(self, rhs: $pty) -> Self::Output {
self.$u(Self::from(rhs))
}
}
impl<T, N: ArrayLength> $t<&$pty> for IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, N, $sign>;
fn $u(self, rhs: &$pty) -> Self::Output {
self.$u(Self::from(*rhs))
}
}
impl<T, N: ArrayLength> $t<$pty> for &IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, N, $sign>;
fn $u(self, rhs: $pty) -> Self::Output {
self.$u(IntVar::<T, N, $sign>::from(rhs))
}
}
impl<T, N: ArrayLength> $t<&$pty> for &IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, N, $sign>;
fn $u(self, rhs: &$pty) -> Self::Output {
self.$u(IntVar::<T, N, $sign>::from(*rhs))
}
}
impl<T, N: ArrayLength> $t<IntVar<T, N, $sign>> for $pty
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, N, $sign>;
fn $u(self, rhs: IntVar<T, N, $sign>) -> Self::Output {
IntVar::<T, N, $sign>::from(self).$u(rhs)
}
}
impl<T, N: ArrayLength> $t<&IntVar<T, N, $sign>> for $pty
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, N, $sign>;
fn $u(self, rhs: &IntVar<T, N, $sign>) -> Self::Output {
IntVar::<T, N, $sign>::from(self).$u(rhs)
}
}
impl<T, N: ArrayLength> $t<IntVar<T, N, $sign>> for &$pty
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, N, $sign>;
fn $u(self, rhs: IntVar<T, N, $sign>) -> Self::Output {
IntVar::<T, N, $sign>::from(*self).$u(rhs)
}
}
impl<T, N: ArrayLength> $t<&IntVar<T, N, $sign>> for &$pty
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, N, $sign>;
fn $u(self, rhs: &IntVar<T, N, $sign>) -> Self::Output {
IntVar::<T, N, $sign>::from(*self).$u(rhs)
}
}
};
}
macro_rules! $macro_upty {
($pty:ty) => {
$macro_gen!(false, $pty);
};
}
macro_rules! $macro_ipty {
($pty:ty) => {
$macro_gen!(true, $pty);
};
}
impl_int_upty!($macro_upty);
impl_int_ipty!($macro_ipty);
};
}
new_op_impl!(BitAnd, bitand, bitand, bitand_gen, bitand_upty, bitand_ipty);
new_op_impl!(BitOr, bitor, bitor, bitor_gen, bitor_upty, bitor_ipty);
new_op_impl!(BitXor, bitxor, bitxor, bitxor_gen, bitxor_upty, bitxor_ipty);
new_op_impl!(
IntModAdd,
mod_add,
mod_add,
modadd_gen,
modadd_upty,
modadd_ipty
);
new_op_impl!(Add, add, mod_add, add_gen, add_upty, add_ipty);
new_op_impl!(
IntModSub,
mod_sub,
mod_sub,
modsub_gen,
modsub_upty,
modsub_ipty
);
new_op_impl!(Sub, sub, mod_sub, sub_gen, sub_upty, sub_ipty);
new_op_impl!(
IntModMul,
mod_mul,
mod_mul,
modmul_gen,
modmul_upty,
modmul_ipty
);
new_op_impl!(Mul, mul, mod_mul, mul_gen, mul_upty, mul_ipty);
macro_rules! new_opassign_impl {
($t:ident, $u:ident, $v:ident, $macro_gen:ident, $macro_upty:ident, $macro_ipty:ident) => {
impl<T, N: ArrayLength, const SIGN: bool> $t<IntVar<T, N, SIGN>> for IntVar<T, N, SIGN>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
{
fn $u(&mut self, rhs: IntVar<T, N, SIGN>) {
self.0.$v(rhs.0);
}
}
impl<T, N: ArrayLength, const SIGN: bool> $t<&IntVar<T, N, SIGN>> for IntVar<T, N, SIGN>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
{
fn $u(&mut self, rhs: &IntVar<T, N, SIGN>) {
self.0.$v(rhs.0.clone());
}
}
macro_rules! $macro_gen {
($sign:expr, $pty:ty) => {
impl<T, N: ArrayLength> $t<$pty> for IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
IntVar<T, N, $sign>: From<$pty>,
{
fn $u(&mut self, rhs: $pty) {
self.$u(Self::from(rhs));
}
}
impl<T, N: ArrayLength> $t<&$pty> for IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
IntVar<T, N, $sign>: From<$pty>,
{
fn $u(&mut self, rhs: &$pty) {
self.$u(Self::from(*rhs));
}
}
};
}
macro_rules! $macro_upty {
($pty:ty) => {
$macro_gen!(false, $pty);
};
}
macro_rules! $macro_ipty {
($pty:ty) => {
$macro_gen!(true, $pty);
};
}
impl_int_upty!($macro_upty);
impl_int_ipty!($macro_ipty);
};
}
new_opassign_impl!(
BitAndAssign,
bitand_assign,
bitand_assign,
bitand_assign_gen,
bitand_assign_upty,
bitand_assign_ipty
);
new_opassign_impl!(
BitOrAssign,
bitor_assign,
bitor_assign,
bitor_assign_gen,
bitor_assign_upty,
bitor_assign_ipty
);
new_opassign_impl!(
BitXorAssign,
bitxor_assign,
bitxor_assign,
bitxor_assign_gen,
bitxor_assign_upty,
bitxor_assign_ipty
);
new_opassign_impl!(
IntModAddAssign,
mod_add_assign,
mod_add_assign,
modadd_assign_gen,
modadd_assign_upty,
modadd_assign_ipty
);
new_opassign_impl!(
AddAssign,
add_assign,
mod_add_assign,
add_assign_gen,
add_assign_upty,
add_assign_ipty
);
new_opassign_impl!(
IntModSubAssign,
mod_sub_assign,
mod_sub_assign,
modsub_assign_gen,
modsub_assign_upty,
modsub_assign_ipty
);
new_opassign_impl!(
SubAssign,
sub_assign,
mod_sub_assign,
sub_assign_gen,
sub_assign_upty,
sub_assign_ipty
);
new_opassign_impl!(
IntModMulAssign,
mod_mul_assign,
mod_mul_assign,
modmul_assign_gen,
modmul_assign_upty,
modmul_assign_ipty
);
new_opassign_impl!(
MulAssign,
mul_assign,
mod_mul_assign,
mul_assign_gen,
mul_assign_upty,
mul_assign_ipty
);
macro_rules! new_condop_impl {
($t:ident, $u:ident, $v:ident, $macro_gen:ident, $macro_upty:ident, $macro_ipty:ident) => {
impl<T, N: ArrayLength, const SIGN: bool> $t<IntVar<T, N, SIGN>> for IntVar<T, N, SIGN>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
{
type Output = IntVar<T, N, SIGN>;
type OutputCond = BoolVar<T>;
fn $u(self, rhs: IntVar<T, N, SIGN>) -> (Self::Output, Self::OutputCond) {
let (r, c) = self.0.$v(rhs.0);
(IntVar(r), c.into())
}
}
impl<T, N: ArrayLength, const SIGN: bool> $t<&IntVar<T, N, SIGN>> for IntVar<T, N, SIGN>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
{
type Output = IntVar<T, N, SIGN>;
type OutputCond = BoolVar<T>;
fn $u(self, rhs: &IntVar<T, N, SIGN>) -> (Self::Output, Self::OutputCond) {
let (r, c) = self.0.$v(rhs.0.clone());
(IntVar(r), c.into())
}
}
impl<T, N: ArrayLength, const SIGN: bool> $t<IntVar<T, N, SIGN>> for &IntVar<T, N, SIGN>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
{
type Output = IntVar<T, N, SIGN>;
type OutputCond = BoolVar<T>;
fn $u(self, rhs: IntVar<T, N, SIGN>) -> (Self::Output, Self::OutputCond) {
let (r, c) = self.0.clone().$v(rhs.0);
(IntVar(r), c.into())
}
}
impl<T, N: ArrayLength, const SIGN: bool> $t<&IntVar<T, N, SIGN>> for &IntVar<T, N, SIGN>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
{
type Output = IntVar<T, N, SIGN>;
type OutputCond = BoolVar<T>;
fn $u(self, rhs: &IntVar<T, N, SIGN>) -> (Self::Output, Self::OutputCond) {
let (r, c) = self.0.clone().$v(rhs.0.clone());
(IntVar(r), c.into())
}
}
macro_rules! $macro_gen {
($sign:expr, $pty:ty) => {
impl<T, N: ArrayLength> $t<$pty> for IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, N, $sign>;
type OutputCond = BoolVar<T>;
fn $u(self, rhs: $pty) -> (Self::Output, Self::OutputCond) {
self.$u(Self::from(rhs))
}
}
impl<T, N: ArrayLength> $t<&$pty> for IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, N, $sign>;
type OutputCond = BoolVar<T>;
fn $u(self, rhs: &$pty) -> (Self::Output, Self::OutputCond) {
self.$u(Self::from(*rhs))
}
}
impl<T, N: ArrayLength> $t<$pty> for &IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, N, $sign>;
type OutputCond = BoolVar<T>;
fn $u(self, rhs: $pty) -> (Self::Output, Self::OutputCond) {
self.$u(IntVar::<T, N, $sign>::from(rhs))
}
}
impl<T, N: ArrayLength> $t<&$pty> for &IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, N, $sign>;
type OutputCond = BoolVar<T>;
fn $u(self, rhs: &$pty) -> (Self::Output, Self::OutputCond) {
self.$u(IntVar::<T, N, $sign>::from(*rhs))
}
}
impl<T, N: ArrayLength> $t<IntVar<T, N, $sign>> for $pty
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, N, $sign>;
type OutputCond = BoolVar<T>;
fn $u(self, rhs: IntVar<T, N, $sign>) -> (Self::Output, Self::OutputCond) {
IntVar::<T, N, $sign>::from(self).$u(rhs)
}
}
impl<T, N: ArrayLength> $t<&IntVar<T, N, $sign>> for $pty
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, N, $sign>;
type OutputCond = BoolVar<T>;
fn $u(self, rhs: &IntVar<T, N, $sign>) -> (Self::Output, Self::OutputCond) {
IntVar::<T, N, $sign>::from(self).$u(rhs)
}
}
impl<T, N: ArrayLength> $t<IntVar<T, N, $sign>> for &$pty
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, N, $sign>;
type OutputCond = BoolVar<T>;
fn $u(self, rhs: IntVar<T, N, $sign>) -> (Self::Output, Self::OutputCond) {
IntVar::<T, N, $sign>::from(*self).$u(rhs)
}
}
impl<T, N: ArrayLength> $t<&IntVar<T, N, $sign>> for &$pty
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, N, $sign>;
type OutputCond = BoolVar<T>;
fn $u(self, rhs: &IntVar<T, N, $sign>) -> (Self::Output, Self::OutputCond) {
IntVar::<T, N, $sign>::from(*self).$u(rhs)
}
}
};
}
macro_rules! $macro_upty {
($pty:ty) => {
$macro_gen!(false, $pty);
};
}
macro_rules! $macro_ipty {
($pty:ty) => {
$macro_gen!(true, $pty);
};
}
impl_int_upty!($macro_upty);
impl_int_ipty!($macro_ipty);
};
}
new_condop_impl!(
IntCondAdd,
cond_add,
cond_add,
condadd_gen,
condadd_upty,
condadd_ipty
);
new_condop_impl!(
IntCondSub,
cond_sub,
cond_sub,
condsub_gen,
condsub_upty,
condsub_ipty
);
macro_rules! condmul_varvar {
($sign:expr) => {
impl<T, N: ArrayLength> IntCondMul<IntVar<T, N, $sign>> for IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
{
type Output = IntVar<T, N, $sign>;
type OutputCond = BoolVar<T>;
fn cond_mul(self, rhs: IntVar<T, N, $sign>) -> (Self::Output, Self::OutputCond) {
let (r, c) = self.0.cond_mul(rhs.0);
(IntVar(r), c.into())
}
}
impl<T, N: ArrayLength> IntCondMul<&IntVar<T, N, $sign>> for IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
{
type Output = IntVar<T, N, $sign>;
type OutputCond = BoolVar<T>;
fn cond_mul(self, rhs: &IntVar<T, N, $sign>) -> (Self::Output, Self::OutputCond) {
let (r, c) = self.0.cond_mul(rhs.0.clone());
(IntVar(r), c.into())
}
}
impl<T, N: ArrayLength> IntCondMul<IntVar<T, N, $sign>> for &IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
{
type Output = IntVar<T, N, $sign>;
type OutputCond = BoolVar<T>;
fn cond_mul(self, rhs: IntVar<T, N, $sign>) -> (Self::Output, Self::OutputCond) {
let (r, c) = self.0.clone().cond_mul(rhs.0);
(IntVar(r), c.into())
}
}
impl<T, N: ArrayLength> IntCondMul<&IntVar<T, N, $sign>> for &IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
{
type Output = IntVar<T, N, $sign>;
type OutputCond = BoolVar<T>;
fn cond_mul(self, rhs: &IntVar<T, N, $sign>) -> (Self::Output, Self::OutputCond) {
let (r, c) = self.0.clone().cond_mul(rhs.0.clone());
(IntVar(r), c.into())
}
}
};
}
condmul_varvar!(false);
condmul_varvar!(true);
macro_rules! condmul_gen {
($sign:expr, $pty:ty) => {
impl<T, N: ArrayLength> IntCondMul<$pty> for IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, N, $sign>;
type OutputCond = BoolVar<T>;
fn cond_mul(self, rhs: $pty) -> (Self::Output, Self::OutputCond) {
self.cond_mul(Self::from(rhs))
}
}
impl<T, N: ArrayLength> IntCondMul<&$pty> for IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, N, $sign>;
type OutputCond = BoolVar<T>;
fn cond_mul(self, rhs: &$pty) -> (Self::Output, Self::OutputCond) {
self.cond_mul(Self::from(*rhs))
}
}
impl<T, N: ArrayLength> IntCondMul<$pty> for &IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, N, $sign>;
type OutputCond = BoolVar<T>;
fn cond_mul(self, rhs: $pty) -> (Self::Output, Self::OutputCond) {
self.cond_mul(IntVar::<T, N, $sign>::from(rhs))
}
}
impl<T, N: ArrayLength> IntCondMul<&$pty> for &IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, N, $sign>;
type OutputCond = BoolVar<T>;
fn cond_mul(self, rhs: &$pty) -> (Self::Output, Self::OutputCond) {
self.cond_mul(IntVar::<T, N, $sign>::from(*rhs))
}
}
impl<T, N: ArrayLength> IntCondMul<IntVar<T, N, $sign>> for $pty
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, N, $sign>;
type OutputCond = BoolVar<T>;
fn cond_mul(self, rhs: IntVar<T, N, $sign>) -> (Self::Output, Self::OutputCond) {
IntVar::<T, N, $sign>::from(self).cond_mul(rhs)
}
}
impl<T, N: ArrayLength> IntCondMul<&IntVar<T, N, $sign>> for $pty
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, N, $sign>;
type OutputCond = BoolVar<T>;
fn cond_mul(self, rhs: &IntVar<T, N, $sign>) -> (Self::Output, Self::OutputCond) {
IntVar::<T, N, $sign>::from(self).cond_mul(rhs)
}
}
impl<T, N: ArrayLength> IntCondMul<IntVar<T, N, $sign>> for &$pty
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, N, $sign>;
type OutputCond = BoolVar<T>;
fn cond_mul(self, rhs: IntVar<T, N, $sign>) -> (Self::Output, Self::OutputCond) {
IntVar::<T, N, $sign>::from(*self).cond_mul(rhs)
}
}
impl<T, N: ArrayLength> IntCondMul<&IntVar<T, N, $sign>> for &$pty
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, N, $sign>;
type OutputCond = BoolVar<T>;
fn cond_mul(self, rhs: &IntVar<T, N, $sign>) -> (Self::Output, Self::OutputCond) {
IntVar::<T, N, $sign>::from(*self).cond_mul(rhs)
}
}
};
}
macro_rules! condmul_upty {
($pty:ty) => {
condmul_gen!(false, $pty);
};
}
macro_rules! condmul_ipty {
($pty:ty) => {
condmul_gen!(true, $pty);
};
}
impl_int_upty!(condmul_upty);
impl_int_ipty!(condmul_ipty);
macro_rules! new_shiftop_impl {
($t:ident, $u:ident, $mimm:ident) => {
impl<T, N, N2, const SIGN: bool, const SIGN2: bool> $t<IntVar<T, N2, SIGN2>>
for IntVar<T, N, SIGN>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
N2: ArrayLength,
{
type Output = Self;
fn $u(self, rhs: IntVar<T, N2, SIGN2>) -> Self::Output {
Self(self.0.$u(rhs.0))
}
}
impl<T, N, N2, const SIGN: bool, const SIGN2: bool> $t<&IntVar<T, N2, SIGN2>>
for IntVar<T, N, SIGN>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
N2: ArrayLength,
{
type Output = Self;
fn $u(self, rhs: &IntVar<T, N2, SIGN2>) -> Self::Output {
Self(self.0.$u(rhs.0.clone()))
}
}
impl<T, N, N2, const SIGN: bool, const SIGN2: bool> $t<IntVar<T, N2, SIGN2>>
for &IntVar<T, N, SIGN>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
N2: ArrayLength,
{
type Output = IntVar<T, N, SIGN>;
fn $u(self, rhs: IntVar<T, N2, SIGN2>) -> Self::Output {
IntVar::<T, N, SIGN>(self.0.clone().$u(rhs.0))
}
}
impl<T, N, N2, const SIGN: bool, const SIGN2: bool> $t<&IntVar<T, N2, SIGN2>>
for &IntVar<T, N, SIGN>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
N2: ArrayLength,
{
type Output = IntVar<T, N, SIGN>;
fn $u(self, rhs: &IntVar<T, N2, SIGN2>) -> Self::Output {
IntVar::<T, N, SIGN>(self.0.clone().$u(rhs.0.clone()))
}
}
macro_rules! $mimm {
($ty:ty) => {
impl<T, N, const SIGN: bool> $t<$ty> for IntVar<T, N, SIGN>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
{
type Output = Self;
fn $u(self, rhs: $ty) -> Self::Output {
Self(self.0.$u(rhs))
}
}
impl<T, N, const SIGN: bool> $t<&$ty> for IntVar<T, N, SIGN>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
{
type Output = Self;
fn $u(self, rhs: &$ty) -> Self::Output {
Self(self.0.$u(*rhs))
}
}
impl<T, N, const SIGN: bool> $t<$ty> for &IntVar<T, N, SIGN>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
{
type Output = IntVar<T, N, SIGN>;
fn $u(self, rhs: $ty) -> Self::Output {
IntVar::<T, N, SIGN>(self.0.clone().$u(rhs))
}
}
impl<T, N, const SIGN: bool> $t<&$ty> for &IntVar<T, N, SIGN>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
{
type Output = IntVar<T, N, SIGN>;
fn $u(self, rhs: &$ty) -> Self::Output {
IntVar::<T, N, SIGN>(self.0.clone().$u(*rhs))
}
}
};
}
impl_int_upty!($mimm);
impl_int_ipty!($mimm);
};
}
macro_rules! new_shiftop_selfimm_impl {
($t:ident, $u:ident, $mselfimm:ident) => {
macro_rules! $mselfimm {
($sign:expr, $ty:ty, $bits:ty) => {
impl<T, N, const SIGN: bool> $t<IntVar<T, N, SIGN>> for $ty
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
{
type Output = IntVar<T, $bits, $sign>;
fn $u(self, rhs: IntVar<T, N, SIGN>) -> Self::Output {
IntVar::<T, $bits, $sign>(self.$u(rhs.0))
}
}
impl<T, N, const SIGN: bool> $t<&IntVar<T, N, SIGN>> for $ty
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
{
type Output = IntVar<T, $bits, $sign>;
fn $u(self, rhs: &IntVar<T, N, SIGN>) -> Self::Output {
IntVar::<T, $bits, $sign>(self.$u(rhs.0.clone()))
}
}
impl<T, N, const SIGN: bool> $t<IntVar<T, N, SIGN>> for &$ty
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
{
type Output = IntVar<T, $bits, $sign>;
fn $u(self, rhs: IntVar<T, N, SIGN>) -> Self::Output {
IntVar::<T, $bits, $sign>((*self).$u(rhs.0))
}
}
impl<T, N, const SIGN: bool> $t<&IntVar<T, N, SIGN>> for &$ty
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
{
type Output = IntVar<T, $bits, $sign>;
fn $u(self, rhs: &IntVar<T, N, SIGN>) -> Self::Output {
IntVar::<T, $bits, $sign>((*self).$u(rhs.0.clone()))
}
}
};
}
$mselfimm!(false, u8, U8);
$mselfimm!(false, u16, U16);
$mselfimm!(false, u32, U32);
#[cfg(target_pointer_width = "32")]
$mselfimm!(false, usize, U32);
#[cfg(target_pointer_width = "64")]
$mselfimm!(false, usize, U64);
$mselfimm!(false, u64, U64);
$mselfimm!(false, u128, U128);
$mselfimm!(true, i8, U8);
$mselfimm!(true, i16, U16);
$mselfimm!(true, i32, U32);
#[cfg(target_pointer_width = "32")]
$mselfimm!(true, isize, U32);
#[cfg(target_pointer_width = "64")]
$mselfimm!(true, isize, U64);
$mselfimm!(true, i64, U64);
$mselfimm!(true, i128, U128);
};
}
new_shiftop_impl!(Shl, shl, impl_shl_imm);
new_shiftop_selfimm_impl!(Shl, shl, impl_shl_self_imm);
new_shiftop_impl!(Shr, shr, impl_shr_imm);
new_shiftop_selfimm_impl!(Shr, shr, impl_shr_self_imm);
new_shiftop_impl!(IntRol, rotate_left, impl_rol_imm);
new_shiftop_impl!(IntRor, rotate_right, impl_ror_imm);
macro_rules! new_condshiftop_impl {
($t:ident, $u:ident, $mselfimm:ident) => {
impl<T, N, N2, const SIGN: bool, const SIGN2: bool> $t<IntVar<T, N2, SIGN2>>
for IntVar<T, N, SIGN>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
N2: ArrayLength,
IntExprNode<T, N2, SIGN2>: TryFrom<IntExprNode<T, U64, false>>,
<IntExprNode<T, N2, SIGN2> as TryFrom<IntExprNode<T, U64, false>>>::Error: Debug,
IntExprNode<T, N2, SIGN2>: IntOrd<Output = BoolExprNode<T>>,
{
type Output = Self;
type OutputCond = BoolVar<T>;
fn $u(self, rhs: IntVar<T, N2, SIGN2>) -> (Self::Output, Self::OutputCond) {
let (r, c) = self.0.$u(rhs.0);
(Self(r), c.into())
}
}
impl<T, N, N2, const SIGN: bool, const SIGN2: bool> $t<&IntVar<T, N2, SIGN2>>
for IntVar<T, N, SIGN>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
N2: ArrayLength,
IntExprNode<T, N2, SIGN2>: TryFrom<IntExprNode<T, U64, false>>,
<IntExprNode<T, N2, SIGN2> as TryFrom<IntExprNode<T, U64, false>>>::Error: Debug,
IntExprNode<T, N2, SIGN2>: IntOrd<Output = BoolExprNode<T>>,
{
type Output = Self;
type OutputCond = BoolVar<T>;
fn $u(self, rhs: &IntVar<T, N2, SIGN2>) -> (Self::Output, Self::OutputCond) {
let (r, c) = self.0.$u(rhs.0.clone());
(Self(r), c.into())
}
}
impl<T, N, N2, const SIGN: bool, const SIGN2: bool> $t<IntVar<T, N2, SIGN2>>
for &IntVar<T, N, SIGN>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
N2: ArrayLength,
IntExprNode<T, N2, SIGN2>: TryFrom<IntExprNode<T, U64, false>>,
<IntExprNode<T, N2, SIGN2> as TryFrom<IntExprNode<T, U64, false>>>::Error: Debug,
IntExprNode<T, N2, SIGN2>: IntOrd<Output = BoolExprNode<T>>,
{
type Output = IntVar<T, N, SIGN>;
type OutputCond = BoolVar<T>;
fn $u(self, rhs: IntVar<T, N2, SIGN2>) -> (Self::Output, Self::OutputCond) {
let (r, c) = self.0.clone().$u(rhs.0);
(IntVar::<T, N, SIGN>(r), c.into())
}
}
impl<T, N, N2, const SIGN: bool, const SIGN2: bool> $t<&IntVar<T, N2, SIGN2>>
for &IntVar<T, N, SIGN>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
N2: ArrayLength,
IntExprNode<T, N2, SIGN2>: TryFrom<IntExprNode<T, U64, false>>,
<IntExprNode<T, N2, SIGN2> as TryFrom<IntExprNode<T, U64, false>>>::Error: Debug,
IntExprNode<T, N2, SIGN2>: IntOrd<Output = BoolExprNode<T>>,
{
type Output = IntVar<T, N, SIGN>;
type OutputCond = BoolVar<T>;
fn $u(self, rhs: &IntVar<T, N2, SIGN2>) -> (Self::Output, Self::OutputCond) {
let (r, c) = self.0.clone().$u(rhs.0.clone());
(IntVar::<T, N, SIGN>(r), c.into())
}
}
macro_rules! $mselfimm {
($sign:expr, $ty:ty, $bits:ty) => {
impl<T, N, const SIGN: bool> $t<IntVar<T, N, SIGN>> for $ty
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
IntExprNode<T, $bits, $sign>: IntConstant<T, $ty>,
IntExprNode<T, N, SIGN>: TryFrom<IntExprNode<T, U64, false>>,
<IntExprNode<T, N, SIGN> as TryFrom<IntExprNode<T, U64, false>>>::Error: Debug,
IntExprNode<T, N, SIGN>: IntOrd<Output = BoolExprNode<T>>,
{
type Output = IntVar<T, $bits, $sign>;
type OutputCond = BoolVar<T>;
fn $u(self, rhs: IntVar<T, N, SIGN>) -> (Self::Output, Self::OutputCond) {
let (r, c) = self.$u(rhs.0);
(IntVar::<T, $bits, $sign>(r), c.into())
}
}
impl<T, N, const SIGN: bool> $t<&IntVar<T, N, SIGN>> for $ty
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
IntExprNode<T, $bits, $sign>: IntConstant<T, $ty>,
IntExprNode<T, N, SIGN>: TryFrom<IntExprNode<T, U64, false>>,
<IntExprNode<T, N, SIGN> as TryFrom<IntExprNode<T, U64, false>>>::Error: Debug,
IntExprNode<T, N, SIGN>: IntOrd<Output = BoolExprNode<T>>,
{
type Output = IntVar<T, $bits, $sign>;
type OutputCond = BoolVar<T>;
fn $u(self, rhs: &IntVar<T, N, SIGN>) -> (Self::Output, Self::OutputCond) {
let (r, c) = self.$u(rhs.0.clone());
(IntVar::<T, $bits, $sign>(r), c.into())
}
}
impl<T, N, const SIGN: bool> $t<IntVar<T, N, SIGN>> for &$ty
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
IntExprNode<T, $bits, $sign>: IntConstant<T, $ty>,
IntExprNode<T, N, SIGN>: TryFrom<IntExprNode<T, U64, false>>,
<IntExprNode<T, N, SIGN> as TryFrom<IntExprNode<T, U64, false>>>::Error: Debug,
IntExprNode<T, N, SIGN>: IntOrd<Output = BoolExprNode<T>>,
{
type Output = IntVar<T, $bits, $sign>;
type OutputCond = BoolVar<T>;
fn $u(self, rhs: IntVar<T, N, SIGN>) -> (Self::Output, Self::OutputCond) {
let (r, c) = (*self).$u(rhs.0);
(IntVar::<T, $bits, $sign>(r), c.into())
}
}
impl<T, N, const SIGN: bool> $t<&IntVar<T, N, SIGN>> for &$ty
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
IntExprNode<T, $bits, $sign>: IntConstant<T, $ty>,
IntExprNode<T, N, SIGN>: TryFrom<IntExprNode<T, U64, false>>,
<IntExprNode<T, N, SIGN> as TryFrom<IntExprNode<T, U64, false>>>::Error: Debug,
IntExprNode<T, N, SIGN>: IntOrd<Output = BoolExprNode<T>>,
{
type Output = IntVar<T, $bits, $sign>;
type OutputCond = BoolVar<T>;
fn $u(self, rhs: &IntVar<T, N, SIGN>) -> (Self::Output, Self::OutputCond) {
let (r, c) = (*self).$u(rhs.0.clone());
(IntVar::<T, $bits, $sign>(r), c.into())
}
}
};
}
$mselfimm!(false, u8, U8);
$mselfimm!(false, u16, U16);
$mselfimm!(false, u32, U32);
#[cfg(target_pointer_width = "32")]
$mselfimm!(false, usize, U32);
#[cfg(target_pointer_width = "64")]
$mselfimm!(false, usize, U64);
$mselfimm!(false, u64, U64);
$mselfimm!(false, u128, U128);
$mselfimm!(true, i8, U8);
$mselfimm!(true, i16, U16);
$mselfimm!(true, i32, U32);
#[cfg(target_pointer_width = "32")]
$mselfimm!(true, isize, U32);
#[cfg(target_pointer_width = "64")]
$mselfimm!(true, isize, U64);
$mselfimm!(true, i64, U64);
$mselfimm!(true, i128, U128);
};
}
new_condshiftop_impl!(IntCondShl, cond_shl, cond_shl_self_imm);
new_condshiftop_impl!(IntCondShr, cond_shr, cond_shr_self_imm);
macro_rules! impl_int_shx_assign {
($trait:ident, $op:ident, $op_assign:ident, $macro:ident) => {
impl<T, N, const SIGN: bool, N2, const SIGN2: bool> $trait<IntVar<T, N2, SIGN2>>
for IntVar<T, N, SIGN>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
N2: ArrayLength,
{
fn $op_assign(&mut self, rhs: IntVar<T, N2, SIGN2>) {
*self = self.clone().$op(rhs)
}
}
impl<T, N, const SIGN: bool, N2, const SIGN2: bool> $trait<&IntVar<T, N2, SIGN2>>
for IntVar<T, N, SIGN>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
N2: ArrayLength,
{
fn $op_assign(&mut self, rhs: &IntVar<T, N2, SIGN2>) {
*self = self.clone().$op(rhs.clone())
}
}
macro_rules! $macro {
($ty:ty) => {
impl<T, N, const SIGN: bool> $trait<$ty> for IntVar<T, N, SIGN>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
{
fn $op_assign(&mut self, rhs: $ty) {
*self = self.clone().$op(rhs)
}
}
impl<T, N, const SIGN: bool> $trait<&$ty> for IntVar<T, N, SIGN>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
{
fn $op_assign(&mut self, rhs: &$ty) {
*self = self.clone().$op(*rhs)
}
}
};
}
impl_int_upty!($macro);
impl_int_ipty!($macro);
};
}
impl_int_shx_assign!(ShlAssign, shl, shl_assign, impl_int_shl_assign_imm);
impl_int_shx_assign!(ShrAssign, shr, shr_assign, impl_int_shr_assign_imm);
macro_rules! impl_fullmul_sign {
($sign:expr) => {
impl<T, N> FullMul<IntVar<T, N, $sign>> for IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength + Add,
<N as Add>::Output: ArrayLength,
{
type Output = IntVar<T, operator_aliases::Sum<N, N>, $sign>;
fn fullmul(self, rhs: Self) -> Self::Output {
IntVar::<T, operator_aliases::Sum<N, N>, $sign>(self.0.fullmul(rhs.0))
}
}
impl<T, N> FullMul<&IntVar<T, N, $sign>> for IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength + Add,
<N as Add>::Output: ArrayLength,
{
type Output = IntVar<T, operator_aliases::Sum<N, N>, $sign>;
fn fullmul(self, rhs: &Self) -> Self::Output {
IntVar::<T, operator_aliases::Sum<N, N>, $sign>(self.0.fullmul(rhs.0.clone()))
}
}
impl<T, N> FullMul<IntVar<T, N, $sign>> for &IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength + Add,
<N as Add>::Output: ArrayLength,
{
type Output = IntVar<T, operator_aliases::Sum<N, N>, $sign>;
fn fullmul(self, rhs: IntVar<T, N, $sign>) -> Self::Output {
IntVar::<T, operator_aliases::Sum<N, N>, $sign>(self.0.clone().fullmul(rhs.0))
}
}
impl<T, N> FullMul<&IntVar<T, N, $sign>> for &IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength + Add,
<N as Add>::Output: ArrayLength,
{
type Output = IntVar<T, operator_aliases::Sum<N, N>, $sign>;
fn fullmul(self, rhs: &IntVar<T, N, $sign>) -> Self::Output {
IntVar::<T, operator_aliases::Sum<N, N>, $sign>(
self.0.clone().fullmul(rhs.0.clone()),
)
}
}
};
}
impl_fullmul_sign!(false);
impl_fullmul_sign!(true);
macro_rules! impl_int_fullmul_pty {
($sign:expr, $pty:ty) => {
impl<T, N> FullMul<$pty> for IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength + Add,
<N as Add>::Output: ArrayLength,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, operator_aliases::Sum<N, N>, $sign>;
fn fullmul(self, rhs: $pty) -> Self::Output {
self.fullmul(Self::from(rhs))
}
}
impl<T, N> FullMul<&$pty> for IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength + Add,
<N as Add>::Output: ArrayLength,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, operator_aliases::Sum<N, N>, $sign>;
fn fullmul(self, rhs: &$pty) -> Self::Output {
self.fullmul(Self::from(*rhs))
}
}
impl<T, N> FullMul<$pty> for &IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength + Add,
<N as Add>::Output: ArrayLength,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, operator_aliases::Sum<N, N>, $sign>;
fn fullmul(self, rhs: $pty) -> Self::Output {
self.fullmul(IntVar::<T, N, $sign>::from(rhs))
}
}
impl<T, N> FullMul<&$pty> for &IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength + Add,
<N as Add>::Output: ArrayLength,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, operator_aliases::Sum<N, N>, $sign>;
fn fullmul(self, rhs: &$pty) -> Self::Output {
self.fullmul(IntVar::<T, N, $sign>::from(*rhs))
}
}
impl<T, N> FullMul<IntVar<T, N, $sign>> for $pty
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength + Add,
<N as Add>::Output: ArrayLength,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, operator_aliases::Sum<N, N>, $sign>;
fn fullmul(self, rhs: IntVar<T, N, $sign>) -> Self::Output {
IntVar::<T, N, $sign>::from(self).fullmul(rhs)
}
}
impl<T, N> FullMul<&IntVar<T, N, $sign>> for $pty
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength + Add,
<N as Add>::Output: ArrayLength,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, operator_aliases::Sum<N, N>, $sign>;
fn fullmul(self, rhs: &IntVar<T, N, $sign>) -> Self::Output {
IntVar::<T, N, $sign>::from(self).fullmul(rhs.clone())
}
}
impl<T, N> FullMul<IntVar<T, N, $sign>> for &$pty
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength + Add,
<N as Add>::Output: ArrayLength,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, operator_aliases::Sum<N, N>, $sign>;
fn fullmul(self, rhs: IntVar<T, N, $sign>) -> Self::Output {
IntVar::<T, N, $sign>::from(*self).fullmul(rhs)
}
}
impl<T, N> FullMul<&IntVar<T, N, $sign>> for &$pty
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength + Add,
<N as Add>::Output: ArrayLength,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, operator_aliases::Sum<N, N>, $sign>;
fn fullmul(self, rhs: &IntVar<T, N, $sign>) -> Self::Output {
IntVar::<T, N, $sign>::from(*self).fullmul(rhs.clone())
}
}
};
}
macro_rules! impl_int_fullmul_upty {
($pty:ty) => {
impl_int_fullmul_pty!(false, $pty);
};
}
macro_rules! impl_int_fullmul_ipty {
($pty:ty) => {
impl_int_fullmul_pty!(true, $pty);
};
}
impl_int_upty!(impl_int_fullmul_upty);
impl_int_ipty!(impl_int_fullmul_ipty);
macro_rules! impl_divmod_sign {
($sign:expr) => {
impl<T, N> DivMod<IntVar<T, N, $sign>> for IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
{
type Output = Self;
type OutputCond = BoolVar<T>;
fn divmod(self, rhs: Self) -> (Self::Output, Self::Output, Self::OutputCond) {
let (d, m, c) = self.0.divmod(rhs.0);
(Self(d), Self(m), c.into())
}
}
impl<T, N> DivMod<&IntVar<T, N, $sign>> for IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
{
type Output = Self;
type OutputCond = BoolVar<T>;
fn divmod(self, rhs: &Self) -> (Self::Output, Self::Output, Self::OutputCond) {
let (d, m, c) = self.0.divmod(rhs.0.clone());
(Self(d), Self(m), c.into())
}
}
impl<T, N> DivMod<IntVar<T, N, $sign>> for &IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
{
type Output = IntVar<T, N, $sign>;
type OutputCond = BoolVar<T>;
fn divmod(
self,
rhs: IntVar<T, N, $sign>,
) -> (Self::Output, Self::Output, Self::OutputCond) {
let (d, m, c) = self.0.clone().divmod(rhs.0);
(IntVar(d), IntVar(m), c.into())
}
}
impl<T, N> DivMod<&IntVar<T, N, $sign>> for &IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
{
type Output = IntVar<T, N, $sign>;
type OutputCond = BoolVar<T>;
fn divmod(
self,
rhs: &IntVar<T, N, $sign>,
) -> (Self::Output, Self::Output, Self::OutputCond) {
let (d, m, c) = self.0.clone().divmod(rhs.0.clone());
(IntVar(d), IntVar(m), c.into())
}
}
};
}
impl_divmod_sign!(false);
impl_divmod_sign!(true);
macro_rules! impl_int_divmod_pty {
($sign:expr, $pty:ty) => {
impl<T, N> DivMod<$pty> for IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, N, $sign>;
type OutputCond = BoolVar<T>;
fn divmod(self, rhs: $pty) -> (Self::Output, Self::Output, Self::OutputCond) {
self.divmod(Self::from(rhs))
}
}
impl<T, N> DivMod<&$pty> for IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, N, $sign>;
type OutputCond = BoolVar<T>;
fn divmod(self, rhs: &$pty) -> (Self::Output, Self::Output, Self::OutputCond) {
self.divmod(Self::from(*rhs))
}
}
impl<T, N> DivMod<$pty> for &IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, N, $sign>;
type OutputCond = BoolVar<T>;
fn divmod(self, rhs: $pty) -> (Self::Output, Self::Output, Self::OutputCond) {
self.divmod(IntVar::<T, N, $sign>::from(rhs))
}
}
impl<T, N> DivMod<&$pty> for &IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, N, $sign>;
type OutputCond = BoolVar<T>;
fn divmod(self, rhs: &$pty) -> (Self::Output, Self::Output, Self::OutputCond) {
self.divmod(IntVar::<T, N, $sign>::from(*rhs))
}
}
impl<T, N> DivMod<IntVar<T, N, $sign>> for $pty
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, N, $sign>;
type OutputCond = BoolVar<T>;
fn divmod(
self,
rhs: IntVar<T, N, $sign>,
) -> (Self::Output, Self::Output, Self::OutputCond) {
IntVar::<T, N, $sign>::from(self).divmod(rhs)
}
}
impl<T, N> DivMod<&IntVar<T, N, $sign>> for $pty
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, N, $sign>;
type OutputCond = BoolVar<T>;
fn divmod(
self,
rhs: &IntVar<T, N, $sign>,
) -> (Self::Output, Self::Output, Self::OutputCond) {
IntVar::<T, N, $sign>::from(self).divmod(rhs.clone())
}
}
impl<T, N> DivMod<IntVar<T, N, $sign>> for &$pty
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, N, $sign>;
type OutputCond = BoolVar<T>;
fn divmod(
self,
rhs: IntVar<T, N, $sign>,
) -> (Self::Output, Self::Output, Self::OutputCond) {
IntVar::<T, N, $sign>::from(*self).divmod(rhs)
}
}
impl<T, N> DivMod<&IntVar<T, N, $sign>> for &$pty
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = IntVar<T, N, $sign>;
type OutputCond = BoolVar<T>;
fn divmod(
self,
rhs: &IntVar<T, N, $sign>,
) -> (Self::Output, Self::Output, Self::OutputCond) {
IntVar::<T, N, $sign>::from(*self).divmod(rhs.clone())
}
}
};
}
macro_rules! impl_int_divmod_upty {
($pty:ty) => {
impl_int_divmod_pty!(false, $pty);
};
}
macro_rules! impl_int_divmod_ipty {
($pty:ty) => {
impl_int_divmod_pty!(true, $pty);
};
}
impl_int_upty!(impl_int_divmod_upty);
impl_int_ipty!(impl_int_divmod_ipty);
macro_rules! impl_int_div_mod {
($sign:expr) => {
impl<T, N> Div<IntVar<T, N, $sign>> for IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
{
type Output = (Self, BoolVar<T>);
fn div(self, rhs: Self) -> Self::Output {
let (d, _, c) = self.divmod(rhs);
(d, c)
}
}
impl<T, N> Div<&IntVar<T, N, $sign>> for IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
{
type Output = (Self, BoolVar<T>);
fn div(self, rhs: &IntVar<T, N, $sign>) -> Self::Output {
let (d, _, c) = self.divmod(rhs);
(d, c)
}
}
impl<T, N> Div<IntVar<T, N, $sign>> for &IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
{
type Output = (IntVar<T, N, $sign>, BoolVar<T>);
fn div(self, rhs: IntVar<T, N, $sign>) -> Self::Output {
let (d, _, c) = self.divmod(rhs);
(d, c)
}
}
impl<T, N> Div<&IntVar<T, N, $sign>> for &IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
{
type Output = (IntVar<T, N, $sign>, BoolVar<T>);
fn div(self, rhs: &IntVar<T, N, $sign>) -> Self::Output {
let (d, _, c) = self.divmod(rhs);
(d, c)
}
}
impl<T, N> Rem<IntVar<T, N, $sign>> for IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
{
type Output = (Self, BoolVar<T>);
fn rem(self, rhs: Self) -> Self::Output {
let (_, r, c) = self.divmod(rhs);
(r, c)
}
}
impl<T, N> Rem<&IntVar<T, N, $sign>> for IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
{
type Output = (Self, BoolVar<T>);
fn rem(self, rhs: &IntVar<T, N, $sign>) -> Self::Output {
let (_, r, c) = self.divmod(rhs);
(r, c)
}
}
impl<T, N> Rem<IntVar<T, N, $sign>> for &IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
{
type Output = (IntVar<T, N, $sign>, BoolVar<T>);
fn rem(self, rhs: IntVar<T, N, $sign>) -> Self::Output {
let (_, r, c) = self.divmod(rhs);
(r, c)
}
}
impl<T, N> Rem<&IntVar<T, N, $sign>> for &IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
{
type Output = (IntVar<T, N, $sign>, BoolVar<T>);
fn rem(self, rhs: &IntVar<T, N, $sign>) -> Self::Output {
let (_, r, c) = self.divmod(rhs);
(r, c)
}
}
};
}
impl_int_div_mod!(false);
impl_int_div_mod!(true);
macro_rules! impl_int_div_mod_op {
($trait:ident, $op:ident, $macro_gen:ident, $macro_upty:ident, $macro_ipty:ident) => {
macro_rules! $macro_gen {
($sign:expr, $pty:ty) => {
impl<T, N> $trait<$pty> for IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = (Self, BoolVar<T>);
fn $op(self, rhs: $pty) -> Self::Output {
self.$op(Self::from(rhs))
}
}
impl<T, N> $trait<&$pty> for IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = (Self, BoolVar<T>);
fn $op(self, rhs: &$pty) -> Self::Output {
self.$op(Self::from(*rhs))
}
}
impl<T, N> $trait<$pty> for &IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = (IntVar<T, N, $sign>, BoolVar<T>);
fn $op(self, rhs: $pty) -> Self::Output {
self.$op(IntVar::<T, N, $sign>::from(rhs))
}
}
impl<T, N> $trait<&$pty> for &IntVar<T, N, $sign>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = (IntVar<T, N, $sign>, BoolVar<T>);
fn $op(self, rhs: &$pty) -> Self::Output {
self.$op(IntVar::<T, N, $sign>::from(*rhs))
}
}
impl<T, N> $trait<IntVar<T, N, $sign>> for $pty
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = (IntVar<T, N, $sign>, BoolVar<T>);
fn $op(self, rhs: IntVar<T, N, $sign>) -> Self::Output {
IntVar::<T, N, $sign>::from(self).$op(rhs)
}
}
impl<T, N> $trait<&IntVar<T, N, $sign>> for $pty
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = (IntVar<T, N, $sign>, BoolVar<T>);
fn $op(self, rhs: &IntVar<T, N, $sign>) -> Self::Output {
IntVar::<T, N, $sign>::from(self).$op(rhs)
}
}
impl<T, N> $trait<IntVar<T, N, $sign>> for &$pty
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = (IntVar<T, N, $sign>, BoolVar<T>);
fn $op(self, rhs: IntVar<T, N, $sign>) -> Self::Output {
IntVar::<T, N, $sign>::from(*self).$op(rhs)
}
}
impl<T, N> $trait<&IntVar<T, N, $sign>> for &$pty
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
IntVar<T, N, $sign>: From<$pty>,
{
type Output = (IntVar<T, N, $sign>, BoolVar<T>);
fn $op(self, rhs: &IntVar<T, N, $sign>) -> Self::Output {
IntVar::<T, N, $sign>::from(*self).$op(rhs)
}
}
};
}
macro_rules! $macro_upty {
($pty:ty) => {
$macro_gen!(false, $pty);
};
}
macro_rules! $macro_ipty {
($pty:ty) => {
$macro_gen!(true, $pty);
};
}
impl_int_upty!($macro_upty);
impl_int_ipty!($macro_ipty);
};
}
impl_int_div_mod_op!(Div, div, int_div_pty, int_div_upty, int_div_ipty);
impl_int_div_mod_op!(Rem, rem, int_rem_pty, int_rem_upty, int_rem_ipty);
impl<T, N, const SIGN: bool> ExtraOps for IntVar<T, N, SIGN>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
{
type Output = Self;
type BoolOutput = BoolVar<T>;
fn count_zeros(self) -> Self::Output {
Self(self.0.count_zeros())
}
fn count_ones(self) -> Self::Output {
Self(self.0.count_ones())
}
fn leading_zeros(self) -> Self::Output {
Self(self.0.leading_zeros())
}
fn leading_ones(self) -> Self::Output {
Self(self.0.leading_ones())
}
fn trailing_zeros(self) -> Self::Output {
Self(self.0.trailing_zeros())
}
fn trailing_ones(self) -> Self::Output {
Self(self.0.trailing_ones())
}
fn is_power_of_two(self) -> Self::BoolOutput {
self.0.is_power_of_two().into()
}
fn reverse_bits(self) -> Self::Output {
Self(self.0.reverse_bits())
}
}
impl<T, N, const SIGN: bool> ExtraOps for &IntVar<T, N, SIGN>
where
T: VarLit + Neg<Output = T> + Debug,
isize: TryFrom<T>,
<T as TryInto<usize>>::Error: Debug,
<T as TryFrom<usize>>::Error: Debug,
<isize as TryFrom<T>>::Error: Debug,
N: ArrayLength,
{
type Output = IntVar<T, N, SIGN>;
type BoolOutput = BoolVar<T>;
fn count_zeros(self) -> Self::Output {
IntVar(self.0.clone().count_zeros())
}
fn count_ones(self) -> Self::Output {
IntVar(self.0.clone().count_ones())
}
fn leading_zeros(self) -> Self::Output {
IntVar(self.0.clone().leading_zeros())
}
fn leading_ones(self) -> Self::Output {
IntVar(self.0.clone().leading_ones())
}
fn trailing_zeros(self) -> Self::Output {
IntVar(self.0.clone().trailing_zeros())
}
fn trailing_ones(self) -> Self::Output {
IntVar(self.0.clone().trailing_ones())
}
fn is_power_of_two(self) -> Self::BoolOutput {
self.0.clone().is_power_of_two().into()
}
fn reverse_bits(self) -> Self::Output {
IntVar(self.0.clone().reverse_bits())
}
}