use crate::ambassador_impl_AsRef;
use crate::ambassador_impl_Index;
use ambassador::{Delegate, delegatable_trait};
use impl_tools::autoimpl;
use mem_dbg::{MemDbg, MemSize};
use std::ops::Deref;
use std::ops::Index;
#[autoimpl(for<T: trait + ?Sized> &T, &mut T, Box<T>)]
#[delegatable_trait]
pub trait BitLength {
fn len(&self) -> usize;
}
#[autoimpl(for<T: trait + ?Sized> &T, &mut T, Box<T>)]
#[delegatable_trait]
pub trait BitCount: BitLength {
fn count_ones(&self) -> usize;
#[inline(always)]
fn count_zeros(&self) -> usize {
self.len() - self.count_ones()
}
}
#[autoimpl(for<T: trait + ?Sized> &T, &mut T, Box<T>)]
#[delegatable_trait]
pub trait NumBits: BitLength {
fn num_ones(&self) -> usize;
#[inline(always)]
fn num_zeros(&self) -> usize {
self.len() - self.num_ones()
}
}
#[autoimpl(for<T: trait + ?Sized> &T, &mut T, Box<T>)]
#[delegatable_trait]
pub trait Rank: BitLength + NumBits + RankUnchecked {
#[inline(always)]
fn rank(&self, pos: usize) -> usize {
if pos >= self.len() {
self.num_ones()
} else {
unsafe { self.rank_unchecked(pos) }
}
}
}
#[autoimpl(for<T: trait + ?Sized> &T, &mut T, Box<T>)]
#[delegatable_trait]
pub trait RankUnchecked {
unsafe fn rank_unchecked(&self, pos: usize) -> usize;
fn prefetch(&self, _pos: usize) {
}
}
#[autoimpl(for<T: trait + ?Sized> &T, &mut T, Box<T>)]
#[delegatable_trait]
pub trait RankZero: Rank {
fn rank_zero(&self, pos: usize) -> usize {
pos - self.rank(pos)
}
unsafe fn rank_zero_unchecked(&self, pos: usize) -> usize {
pos - unsafe { self.rank_unchecked(pos) }
}
}
#[autoimpl(for<T: trait + ?Sized> &T, &mut T, Box<T>)]
#[delegatable_trait]
pub trait RankHinted<const HINT_BIT_SIZE: usize> {
unsafe fn rank_hinted(&self, pos: usize, hint_pos: usize, hint_rank: usize) -> usize;
}
#[autoimpl(for<T: trait + ?Sized> &T, &mut T, Box<T>)]
#[delegatable_trait]
pub trait SelectUnchecked {
unsafe fn select_unchecked(&self, rank: usize) -> usize;
}
#[autoimpl(for<T: trait + ?Sized> &T, &mut T, Box<T>)]
#[delegatable_trait]
pub trait Select: SelectUnchecked + NumBits {
fn select(&self, rank: usize) -> Option<usize> {
if rank >= self.num_ones() {
None
} else {
Some(unsafe { self.select_unchecked(rank) })
}
}
}
#[autoimpl(for<T: trait + ?Sized> &T, &mut T, Box<T>)]
#[delegatable_trait]
pub trait SelectZeroUnchecked {
unsafe fn select_zero_unchecked(&self, rank: usize) -> usize;
}
#[autoimpl(for<T: trait + ?Sized> &T, &mut T, Box<T>)]
#[delegatable_trait]
pub trait SelectZero: SelectZeroUnchecked + NumBits {
fn select_zero(&self, rank: usize) -> Option<usize> {
if rank >= self.num_zeros() {
None
} else {
Some(unsafe { self.select_zero_unchecked(rank) })
}
}
}
#[autoimpl(for<T: trait + ?Sized> &T, &mut T, Box<T>)]
#[delegatable_trait]
pub trait SelectHinted {
unsafe fn select_hinted(&self, rank: usize, hint_pos: usize, hint_rank: usize) -> usize;
}
#[autoimpl(for<T: trait + ?Sized> &T, &mut T, Box<T>)]
#[delegatable_trait]
pub trait SelectZeroHinted {
unsafe fn select_zero_hinted(&self, rank: usize, hint_pos: usize, hint_rank: usize) -> usize;
}
#[derive(Debug, Clone, MemDbg, MemSize, Delegate)]
#[cfg_attr(feature = "epserde", derive(epserde::Epserde))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[delegate(AsRef<[usize]>, target = "bits")]
#[delegate(Index<usize>, target = "bits")]
#[delegate(crate::traits::rank_sel::BitLength, target = "bits")]
#[delegate(crate::traits::rank_sel::Rank, target = "bits")]
#[delegate(crate::traits::rank_sel::RankHinted<64>, target = "bits")]
#[delegate(crate::traits::rank_sel::RankUnchecked, target = "bits")]
#[delegate(crate::traits::rank_sel::RankZero, target = "bits")]
#[delegate(crate::traits::rank_sel::Select, target = "bits")]
#[delegate(crate::traits::rank_sel::SelectHinted, target = "bits")]
#[delegate(crate::traits::rank_sel::SelectUnchecked, target = "bits")]
#[delegate(crate::traits::rank_sel::SelectZero, target = "bits")]
#[delegate(crate::traits::rank_sel::SelectZeroHinted, target = "bits")]
#[delegate(crate::traits::rank_sel::SelectZeroUnchecked, target = "bits")]
pub struct AddNumBits<B> {
bits: B,
number_of_ones: usize,
}
impl<B> AddNumBits<B> {
pub fn into_inner(self) -> B {
self.bits
}
#[inline(always)]
pub unsafe fn from_raw_parts(bits: B, number_of_ones: usize) -> Self {
Self {
bits,
number_of_ones,
}
}
#[inline(always)]
pub fn into_raw_parts(self) -> (B, usize) {
(self.bits, self.number_of_ones)
}
}
impl<B: BitLength> AddNumBits<B> {
#[inline(always)]
pub fn len(&self) -> usize {
BitLength::len(self)
}
}
impl<B: BitLength> NumBits for AddNumBits<B> {
#[inline(always)]
fn num_ones(&self) -> usize {
self.number_of_ones
}
}
impl<B: BitLength> BitCount for AddNumBits<B> {
#[inline(always)]
fn count_ones(&self) -> usize {
self.number_of_ones
}
}
impl<B> Deref for AddNumBits<B> {
type Target = B;
fn deref(&self) -> &Self::Target {
&self.bits
}
}
impl<B: BitCount> From<B> for AddNumBits<B> {
fn from(bits: B) -> Self {
let number_of_ones = bits.count_ones();
AddNumBits {
bits,
number_of_ones,
}
}
}