#![no_std]
pub trait CFuncInt {
#[must_use]
fn inc_post(&mut self) -> Self;
#[must_use]
fn dec_post(&mut self) -> Self;
#[must_use]
fn pre_inc(&mut self) -> Self;
#[must_use]
fn pre_dec(&mut self) -> Self;
#[must_use]
fn c_add_assign(&mut self, rhs: Self) -> Self;
#[must_use]
fn c_sub_assign(&mut self, rhs: Self) -> Self;
#[must_use]
fn c_mul_assign(&mut self, rhs: Self) -> Self;
#[must_use]
fn c_div_assign(&mut self, rhs: Self) -> Self;
#[must_use]
fn c_mod_assign(&mut self, rhs: Self) -> Self;
#[must_use]
fn c_rshift_assign(&mut self, rhs: Self) -> Self;
#[must_use]
fn c_lshift_assign(&mut self, rhs: Self) -> Self;
#[must_use]
fn c_and_assign(&mut self, rhs: Self) -> Self;
#[must_use]
fn c_or_assign(&mut self, rhs: Self) -> Self;
#[must_use]
fn c_xor_assign(&mut self, rhs: Self) -> Self;
}
pub trait CFuncFloat {
#[must_use]
fn inc_post(&mut self) -> Self;
#[must_use]
fn dec_post(&mut self) -> Self;
#[must_use]
fn pre_inc(&mut self) -> Self;
#[must_use]
fn pre_dec(&mut self) -> Self;
#[must_use]
fn c_add_assign(&mut self, rhs: Self) -> Self;
#[must_use]
fn c_sub_assign(&mut self, rhs: Self) -> Self;
#[must_use]
fn c_mul_assign(&mut self, rhs: Self) -> Self;
#[must_use]
fn c_div_assign(&mut self, rhs: Self) -> Self;
}
pub trait CFuncPoint {
#[must_use]
unsafe fn inc_post(&mut self) -> Self;
#[must_use]
unsafe fn dec_post(&mut self) -> Self;
#[must_use]
unsafe fn pre_inc(&mut self) -> Self;
#[must_use]
unsafe fn pre_dec(&mut self) -> Self;
#[must_use]
unsafe fn c_add_assign(&mut self, rhs: isize) -> Self;
#[must_use]
unsafe fn c_sub_assign(&mut self, rhs: isize) -> Self;
#[must_use]
unsafe fn c_add(self, rhs: isize) -> Self;
#[must_use]
unsafe fn c_sub(self, rhs: isize) -> Self;
}
pub trait CAssign {
#[must_use]
fn c_assign(&mut self, rhs: Self) -> Self;
}
pub trait CIndex {
type IndType;
unsafe fn index(&self, n: usize) -> Self::IndType;
}
macro_rules! impl_assign {
($name:ident,$op:tt) => {
fn $name(&mut self, rhs: Self) -> Self {
*self $op rhs;
*self
}
};
}
macro_rules! impl_cfunc {
($t:ty) => {
impl CFuncInt for $t {
fn inc_post(&mut self) -> Self {
let res=*self;
*self+=1;
res
}
fn dec_post(&mut self) -> Self {
let res=*self;
*self-=1;
res
}
fn pre_inc(&mut self) -> Self {
self.c_add_assign(1)
}
fn pre_dec(&mut self) -> Self {
self.c_sub_assign(1)
}
impl_assign!(c_add_assign,+=);
impl_assign!(c_sub_assign,-=);
impl_assign!(c_mul_assign,*=);
impl_assign!(c_div_assign,/=);
impl_assign!(c_mod_assign,%=);
impl_assign!(c_lshift_assign,<<=);
impl_assign!(c_rshift_assign,>>=);
impl_assign!(c_and_assign,&=);
impl_assign!(c_xor_assign,^=);
impl_assign!(c_or_assign,|=);
}
};
($t:ty,$($u:ty),*) => {
impl_cfunc!($t);
impl_cfunc!($($u),*);
};
(float $t:ty) => {
impl CFuncFloat for $t {
fn inc_post(&mut self) -> Self {
let res=*self;
*self+=1.0;
res
}
fn dec_post(&mut self) -> Self {
let res=*self;
*self-=1.0;
res
}
fn pre_inc(&mut self) -> Self {
self.c_add_assign(1.0)
}
fn pre_dec(&mut self) -> Self {
self.c_sub_assign(1.0)
}
impl_assign!(c_add_assign,+=);
impl_assign!(c_sub_assign,-=);
impl_assign!(c_mul_assign,*=);
impl_assign!(c_div_assign,/=);
}
};
(float $t:ty,$($u:ty),*) => {
impl_cfunc!(float $t);
impl_cfunc!(float $($u),*);
};
}
impl_cfunc!(i8,u8,i16,u16,i32,u32,i64,u64,i128,u128,isize,usize);
impl_cfunc!(float f32,f64);
impl<T> CFuncPoint for *const [T] {
unsafe fn inc_post(&mut self) -> Self {
let res=*self;
unsafe { *self=self.c_add(1) };
res
}
unsafe fn dec_post(&mut self) -> Self {
let res=*self;
unsafe { *self=self.c_sub(1) };
res
}
unsafe fn pre_inc(&mut self) -> Self {
unsafe { self.c_add_assign(1) }
}
unsafe fn pre_dec(&mut self) -> Self {
unsafe { self.c_sub_assign(1) }
}
unsafe fn c_add_assign(&mut self, rhs: isize) -> Self {
unsafe { *self=self.c_add(rhs) };
*self
}
unsafe fn c_sub_assign(&mut self, rhs: isize) -> Self {
unsafe { *self=self.c_sub(rhs) };
*self
}
#[allow(clippy::not_unsafe_ptr_arg_deref)]
unsafe fn c_add(self, rhs: isize) -> Self {
let n=rhs.unsigned_abs();
if rhs>=0 { unsafe { self.byte_add(n*size_of::<T>()) } }
else { unsafe { self.byte_sub(n*size_of::<T>()) } }
}
unsafe fn c_sub(self, rhs: isize) -> Self {
unsafe { self.c_add(-rhs) }
}
}
impl<T> CFuncPoint for *mut [T] {
unsafe fn inc_post(&mut self) -> Self {
let res=*self;
unsafe { *self=self.c_add(1) };
res
}
unsafe fn dec_post(&mut self) -> Self {
let res=*self;
unsafe { *self=self.c_sub(1) };
res
}
unsafe fn pre_inc(&mut self) -> Self {
unsafe { self.c_add_assign(1) }
}
unsafe fn pre_dec(&mut self) -> Self {
unsafe { self.c_sub_assign(1) }
}
unsafe fn c_add_assign(&mut self, rhs: isize) -> Self {
unsafe { *self=self.c_add(rhs) };
*self
}
unsafe fn c_sub_assign(&mut self, rhs: isize) -> Self {
unsafe { *self=self.c_sub(rhs) };
*self
}
#[allow(clippy::not_unsafe_ptr_arg_deref)]
unsafe fn c_add(self, rhs: isize) -> Self {
let n=rhs.unsigned_abs();
if rhs>=0 { unsafe { self.byte_add(n*size_of::<T>()) } }
else { unsafe { self.byte_sub(n*size_of::<T>()) } }
}
unsafe fn c_sub(self, rhs: isize) -> Self {
unsafe { self.c_add(-rhs) }
}
}
impl<T: Copy> CAssign for T {
fn c_assign(&mut self, rhs: Self) -> Self {
*self=rhs;
*self
}
}
impl<T: Copy> CIndex for *const T {
type IndType = T;
unsafe fn index(&self,n: usize) -> Self::IndType {
*unsafe { self.add(n).as_ref() }.unwrap()
}
}
impl<T: Copy> CIndex for *mut T {
type IndType = T;
unsafe fn index(&self,n: usize) -> Self::IndType {
*unsafe { self.add(n).as_ref() }.unwrap()
}
}