multindex 0.1.3

Index slices with multiple const indices/ranges.
Documentation
use crate::index_argument::{IK_Index, IK_Range, IK_RangeFrom};

use core::marker::PhantomData;

pub struct IndexerParams {
    pub index: isize,
    pub slice_len: usize,
}

impl IndexerParams {
    #[inline(always)]
    pub fn build<Elem, RetArray, IK>(self) -> Indexer<Elem, RetArray, IK> {
        Indexer {
            index: self.index,
            slice_len: self.slice_len,
            _marker: PhantomData,
        }
    }
}

pub struct Indexer<Elem, RetArray, IK> {
    index: isize,
    slice_len: usize,
    _marker: PhantomData<fn() -> (Elem, RetArray, IK)>,
}

pub trait IndexPointer {
    type Elem;
    type Output: ?Sized;

    unsafe fn index_ptr<'a>(
        self,
        base: *const Self::Elem,
        lt: PhantomData<&'a Self::Elem>,
    ) -> &'a Self::Output;
    unsafe fn index_ptr_mut<'a>(
        self,
        base: *mut Self::Elem,
        lt: PhantomData<&'a mut Self::Elem>,
    ) -> &'a mut Self::Output;
}

impl<T, RetArray> IndexPointer for Indexer<T, RetArray, IK_Index> {
    type Elem = T;
    type Output = T;

    #[inline(always)]
    unsafe fn index_ptr<'a>(
        self,
        base: *const Self::Elem,
        _: PhantomData<&'a T>,
    ) -> &'a Self::Output {
        &*base.offset(self.index)
    }

    #[inline(always)]
    unsafe fn index_ptr_mut<'a>(
        self,
        base: *mut Self::Elem,
        _: PhantomData<&'a mut T>,
    ) -> &'a mut Self::Output {
        &mut *base.offset(self.index)
    }
}

impl<T, RetArray> IndexPointer for Indexer<T, RetArray, IK_Range> {
    type Elem = T;
    type Output = RetArray;

    #[inline(always)]
    unsafe fn index_ptr<'a>(
        self,
        base: *const Self::Elem,
        _: PhantomData<&'a T>,
    ) -> &'a Self::Output {
        &*(base.offset(self.index) as *const RetArray)
    }

    #[inline(always)]
    unsafe fn index_ptr_mut<'a>(
        self,
        base: *mut Self::Elem,
        _: PhantomData<&'a mut T>,
    ) -> &'a mut Self::Output {
        &mut *(base.offset(self.index) as *mut RetArray)
    }
}

impl<T, RetArray> IndexPointer for Indexer<T, RetArray, IK_RangeFrom> {
    type Elem = T;
    type Output = [T];

    #[inline(always)]
    unsafe fn index_ptr<'a>(
        self,
        base: *const Self::Elem,
        _: PhantomData<&'a T>,
    ) -> &'a Self::Output {
        core::slice::from_raw_parts(
            base.offset(self.index),
            self.slice_len - self.index as usize,
        )
    }

    #[inline(always)]
    unsafe fn index_ptr_mut<'a>(
        self,
        base: *mut Self::Elem,
        _: PhantomData<&'a mut T>,
    ) -> &'a mut Self::Output {
        core::slice::from_raw_parts_mut(
            base.offset(self.index),
            self.slice_len - self.index as usize,
        )
    }
}