allocator-suite 0.1.7

Allocator Suite for various allocation types
use crate::allocators::bit_set::absolute_location_in_bit_set::AbsoluteLocationInBitSet;
use crate::allocators::bit_set::bit_set_word::BitSetWord;
use crate::allocators::bit_set::bit_set_word_pointer::BitSetWordPointer;
use crate::allocators::bit_set::block_size::BlockSize;
use crate::allocators::bit_set::number_of_bit_set_words::NumberOfBitSetWords;
use crate::allocators::bit_set::number_of_bytes::NumberOfBytes;
use crate::allocators::bit_set::relative_location_in_bit_set::RelativeLocationInBitSet;
use std::ops::{Add, Shr, Sub, SubAssign};

#[derive(Default, Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
pub struct NumberOfBits(pub usize);

impl Add for NumberOfBits {
    type Output = Self;

    #[inline(always)]
    fn add(self, other: Self) -> Self::Output {
        Self(self.0 + other.0)
    }
}

impl Add<usize> for NumberOfBits {
    type Output = Self;

    #[inline(always)]
    fn add(self, other: usize) -> Self::Output {
        Self(self.0 + other)
    }
}

impl Sub for NumberOfBits {
    type Output = Self;

    #[inline(always)]
    fn sub(self, other: Self) -> Self::Output {
        debug_assert!(
            self >= other,
            "self `{:?}` is less than other `{:?}`",
            self,
            other
        );

        Self(self.0 - other.0)
    }
}

impl SubAssign for NumberOfBits {
    #[inline(always)]
    fn sub_assign(&mut self, other: Self) {
        debug_assert!(
            self.0 >= other.0,
            "self `{:?}` is less than other `{:?}`",
            self,
            other
        );

        self.0 -= other.0
    }
}

impl Shr<usize> for NumberOfBits {
    type Output = Self;

    #[inline(always)]
    fn shr(self, rhs: usize) -> Self::Output {
        Self(self.0 >> rhs)
    }
}

impl NumberOfBits {
    pub(crate) const ZERO: Self = Self(0);

    pub(crate) const IN_BIT_SET_WORD: Self = Self(BitSetWord::SIZE_IN_BITS);

    #[inline(always)]
    pub(crate) fn is_zero(self) -> bool {
        self == Self::ZERO
    }

    #[inline(always)]
    pub(crate) fn is_not_zero(self) -> bool {
        self != Self::ZERO
    }

    #[inline(always)]
    pub(crate) fn to_usize(self) -> usize {
        self.0 as usize
    }

    #[inline(always)]
    pub(crate) fn to_u64(self) -> u64 {
        self.0 as u64
    }

    #[inline(always)]
    pub(crate) fn remainder_of_bits_that_do_not_fit_in_a_bit_set_word(self) -> Self {
        Self(self.0 % BitSetWord::SIZE_IN_BITS)
    }

    #[inline(always)]
    pub(crate) fn round_up_to_number_of_bit_set_words(self) -> NumberOfBitSetWords {
        NumberOfBitSetWords((self.0 + BitSetWord::SIZE_IN_BITS - 1) / BitSetWord::SIZE_IN_BITS)
    }

    #[inline(always)]
    pub(crate) fn scale_to_memory_offset_in_bytes(self, block_size: &BlockSize) -> NumberOfBytes {
        block_size.scale_to_memory_offset_in_bytes(self.0)
    }

    #[inline(always)]
    pub(crate) fn to_absolute_location_in_bit_set(
        self,
        inclusive_start_of_bitset: BitSetWordPointer,
    ) -> AbsoluteLocationInBitSet {
        self.to_relative_location_in_bit_set()
            .to_absolute_location_in_bit_set(inclusive_start_of_bitset)
    }

    #[inline(always)]
    pub(crate) fn to_relative_location_in_bit_set(self) -> RelativeLocationInBitSet {
        let major = self.number_of_bit_set_words_rounded_down();
        let minor = self - major.to_number_of_bits();
        RelativeLocationInBitSet { major, minor }
    }

    #[inline(always)]
    pub(crate) fn is_one_bit_set_word(self) -> bool {
        self.0 == BitSetWord::SIZE_IN_BITS
    }

    #[inline(always)]
    pub(crate) fn less_than_a_bit_set_word_required(self) -> bool {
        self.0 < BitSetWord::SIZE_IN_BITS
    }

    #[inline(always)]
    pub(crate) fn number_of_bit_set_words_rounded_down(self) -> NumberOfBitSetWords {
        NumberOfBitSetWords(self.0 / BitSetWord::SIZE_IN_BITS)
    }
}