use crate::error::NonUniqueIndex;
use crate::index::combinators::{
IndexAZip, IndexCast, IndexFlatten, IndexProduct, IndexTranspose, IndexZip,
};
use crate::index::{AssumedUnique, CheckedUnique};
use crate::{Bounds, IndexFrom, RecordIndex};
pub unsafe trait IndexList: Sync + Send {
type Index: Copy;
const ALWAYS_BOUNDED: bool;
unsafe fn get_index_unchecked(&self, loc: usize) -> Self::Index;
fn num_indices(&self) -> usize;
fn bounds(&self) -> Option<Bounds<Self::Index>>;
fn get_index(&self, loc: usize) -> Self::Index {
assert!(loc < self.num_indices(), "Index must be in bounds");
unsafe { self.get_index_unchecked(loc) }
}
fn index_cast<TargetIndex>(self) -> IndexCast<Self, TargetIndex>
where
Self: Sized,
TargetIndex: Copy + IndexFrom<Self::Index>,
{
IndexCast {
source_indices: self,
marker: Default::default(),
}
}
fn index_product<I: IndexList>(self, other: I) -> IndexProduct<Self, I>
where
Self: Sized,
{
IndexProduct(self, other)
}
fn index_zip<I: IndexList>(self, other: I) -> IndexZip<Self, I>
where
Self: Sized,
{
IndexZip::new(self, other)
}
fn index_azip<I: IndexList>(self, other: I) -> IndexAZip<Self, I>
where
Self: Sized,
{
IndexAZip::new(self, other)
}
fn index_flatten(self) -> IndexFlatten<Self>
where
Self: Sized,
{
IndexFlatten(self)
}
fn index_transpose(self) -> IndexTranspose<Self>
where
Self: Sized,
{
IndexTranspose(self)
}
fn check_unique(self) -> Result<CheckedUnique<Self>, NonUniqueIndex>
where
Self: Sized,
Self::Index: RecordIndex,
{
CheckedUnique::from_hashable_indices(self)
}
unsafe fn assume_unique(self) -> AssumedUnique<Self>
where
Self: Sized,
{
unsafe { AssumedUnique::assume_unique(self) }
}
}
unsafe impl<'a, I: IndexList> IndexList for &'a I {
type Index = I::Index;
const ALWAYS_BOUNDED: bool = I::ALWAYS_BOUNDED;
unsafe fn get_index_unchecked(&self, loc: usize) -> Self::Index {
unsafe { I::get_index_unchecked(self, loc) }
}
fn num_indices(&self) -> usize {
I::num_indices(self)
}
fn bounds(&self) -> Option<Bounds<Self::Index>> {
I::bounds(self)
}
}
pub unsafe trait UniqueIndexList: IndexList {}
unsafe impl<'a, I: UniqueIndexList> UniqueIndexList for &'a I {}