use crate::{
cursor::Cursor,
indices::BitIdx,
store::BitStore,
};
use core::{
fmt::Debug,
sync::atomic::Ordering,
};
use radium::{
Radium,
marker::BitOps,
};
pub trait BitAccess<T>: Debug + Radium<T> + Sized
where T: BitStore + BitOps + Sized {
#[inline(always)]
fn clear_bit<C>(&self, place: BitIdx<T>)
where C: Cursor {
self.fetch_and(!*C::mask(place), Ordering::Relaxed);
}
fn clear_bits(&self, mask: T) {
self.fetch_and(mask, Ordering::Relaxed);
}
#[inline(always)]
fn set_bit<C>(&self, place: BitIdx<T>)
where C: Cursor {
self.fetch_or(*C::mask(place), Ordering::Relaxed);
}
fn set_bits(&self, mask: T) {
self.fetch_or(mask, Ordering::Relaxed);
}
#[inline(always)]
fn invert_bit<C>(&self, place: BitIdx<T>)
where C: Cursor {
self.fetch_xor(*C::mask(place), Ordering::Relaxed);
}
#[inline]
fn get<C>(&self, place: BitIdx<T>) -> bool
where C: Cursor {
<Self as BitAccess<T>>::load(&self) & *C::mask(place) != T::FALSE
}
#[inline]
fn set<C>(&self, place: BitIdx<T>, value: bool)
where C: Cursor {
if value {
self.set_bit::<C>(place);
}
else {
self.clear_bit::<C>(place);
}
}
fn load(&self) -> T {
Radium::load(self, Ordering::Relaxed)
}
fn store(&self, value: T) {
Radium::store(self, value, Ordering::Relaxed)
}
#[allow(clippy::mut_from_ref)] unsafe fn as_slice_mut(this: &[Self]) -> &mut [T] {
&mut *(this as *const [Self] as *const [T] as *mut [T])
}
}
impl<T, R> BitAccess<T> for R
where T: BitStore + BitOps, R: Debug + Radium<T> {}