pub(crate) struct SelectIndicesBase<'a, T, I>
{
pub(crate) data: T,
pub(crate) indices: &'a [I],
pub(crate) start: usize,
pub(crate) end: usize,
}
use num_traits::{ PrimInt, ToPrimitive };
use std::collections::HashSet;
impl<T, I: Copy + Clone + PrimInt + ToPrimitive> SelectIndicesBase<'_, &[T], I>
{
pub(crate) fn safety_check(slice: &[T], indices: &[I])
{
let len = slice.len();
let indices_len = indices.len();
indices.iter().for_each(|&i| {
let i = i.to_usize()
.expect("select_indices was given indices that cannot be converted to usize!");
assert!(i < len, "select_indices was given an out-of-bounds index!");
});
}
}
impl<T, I: Copy + Clone + PrimInt + ToPrimitive> SelectIndicesBase<'_, &mut [T], I>
{
pub(crate) fn safety_check(slice: &mut [T], indices: &[I])
{
let len = slice.len();
let indices_len = indices.len();
assert!(indices_len <= len,
"select_indices_mut was passed more indices than are possible without breaking mutability rules!");
let mut indexset = HashSet::with_capacity(indices_len);
indices.iter().for_each(|&i| {
let i = i.to_usize()
.expect("select_indices_mut was given indices that cannot be converted to usize!");
assert!(i < len, "select_indices_mut was passed an out-of-bounds index!");
assert!(indexset.insert(i), "select_indices_mut was passed a duplicate index!");
});
}
}
impl<'a, T: 'a, I: Copy + Clone + PrimInt + ToPrimitive> Iterator for SelectIndicesBase<'a, &'a [T], I>
{
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
if self.start < self.end
{
let ind = unsafe { *self.indices.get_unchecked(self.start) };
self.start += 1;
return Some(unsafe {
self.data.get_unchecked(
ind.to_usize()
.expect("select_indices was given indices that cannot be converted to usize!")
)
});
}
else {
return None;
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.indices.len();
return (len, Some(len));
}
}
impl<'a, T: 'a, I: Copy + Clone + PrimInt + ToPrimitive> DoubleEndedIterator for SelectIndicesBase<'a, &'a [T], I>
{
fn next_back(&mut self) -> Option<Self::Item> {
if self.start < self.end
{
self.end -= 1;
let ind = unsafe { * self.indices.get_unchecked(self.end) };
return Some(unsafe {
self.data.get_unchecked(
ind.to_usize()
.expect("select_indices was given indices that cannot be converted to usize!")
)
});
}
else {
return None;
}
}
}
impl<'a, T: 'a, I: Copy + Clone + PrimInt + ToPrimitive> ExactSizeIterator for SelectIndicesBase<'a, &'a [T], I> {}
impl<'a, T: 'a, I: Copy + Clone + PrimInt + ToPrimitive> Iterator for SelectIndicesBase<'a, &'a mut [T], I>
{
type Item = &'a mut T;
fn next(&mut self) -> Option<Self::Item> {
if self.start < self.end
{
let ind = unsafe { *self.indices.get_unchecked(self.start) };
self.start += 1;
return Some(unsafe {
&mut *self.data.as_mut_ptr().add(
ind.to_usize()
.expect("select_indices was given indices that cannot be converted to usize!")
)
});
}
else {
return None;
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.indices.len();
return (len, Some(len));
}
}
impl<'a, T: 'a, I: Copy + Clone + PrimInt + ToPrimitive> DoubleEndedIterator for SelectIndicesBase<'a, &'a mut [T], I>
{
fn next_back(&mut self) -> Option<Self::Item> {
if self.start < self.end
{
self.end -= 1;
let ind = unsafe { *self.indices.get_unchecked(self.end) };
return Some(unsafe {
&mut *self.data.as_mut_ptr().add(
ind.to_usize()
.expect("select_indices was given indices that cannot be converted to usize!")
)
});
}
else {
return None;
}
}
}
impl<'a, T: 'a, I: Copy + Clone + PrimInt + ToPrimitive> ExactSizeIterator for SelectIndicesBase<'a, &'a mut [T], I> {}