use std::slice::SliceIndex;
use crate::traits::BacktrackingIterator;
pub struct BacktrackingSlice<'slice, Slice> where Slice: ?Sized {
slice: &'slice Slice,
current_position: usize,
}
impl<'slice, Slice: ?Sized> From<&'slice Slice> for BacktrackingSlice<'slice, Slice> {
fn from(slice: &'slice Slice) -> Self {
BacktrackingSlice {
slice: slice,
current_position: 0_usize,
}
}
}
impl<'slice, Slice: ?Sized> Iterator for BacktrackingSlice<'slice, Slice> where usize: SliceIndex<Slice> {
type Item = &'slice <usize as SliceIndex<Slice>>::Output;
fn next(&mut self) -> Option<Self::Item> {
let value = self.current_position.get(self.slice);
self.current_position += 1;
value
}
}
impl<'slice, Slice: ?Sized> BacktrackingIterator for BacktrackingSlice<'slice, Slice> where usize: SliceIndex<Slice> {
type RefPoint = usize;
fn get_ref_point(&self) -> usize {
self.current_position
}
fn get_oldest_point(&self) -> usize {
0_usize
}
fn backtrack(&mut self, point: usize) {
self.current_position = point;
}
}
use std::ops::{RangeBounds, Range, RangeFull, RangeFrom, RangeInclusive, RangeTo, RangeToInclusive};
use crate::sliceable::SliceableIterator;
impl<'slice, Slice: ?Sized> SliceableIterator for BacktrackingSlice<'slice, Slice> where
usize: SliceIndex<Slice>,
Range<usize>: SliceIndex<Slice, Output=Slice>,
RangeFull: SliceIndex<Slice, Output=Slice>,
RangeFrom<usize>: SliceIndex<Slice, Output=Slice>,
RangeInclusive<usize>: SliceIndex<Slice, Output=Slice>,
RangeTo<usize>: SliceIndex<Slice, Output=Slice>,
RangeToInclusive<usize>: SliceIndex<Slice, Output=Slice>,
{
type Slice = Slice;
fn slice(&self, range: impl RangeBounds<usize>) -> Option<&Slice> {
use std::ops::Bound::*;
match (range.start_bound(), range.end_bound()) {
(Unbounded, Unbounded) => (..).get(self.slice),
(Unbounded, Included(&end)) => (..=end).get(self.slice),
(Unbounded, Excluded(&end)) => (..end).get(self.slice),
(Included(&start), Unbounded) => (start..).get(self.slice),
(Excluded(&start), Unbounded) => ((start+1)..).get(self.slice),
(Included(&start), Included(&end)) => (start..=end).get(self.slice),
(Included(&start), Excluded(&end)) => (start..end).get(self.slice),
(Excluded(&start), Included(&end)) => (start+1..=end).get(self.slice),
(Excluded(&start), Excluded(&end)) => (start+1..end).get(self.slice),
}
}
}
sliceable_indexing!(<'slice, Slice>, BacktrackingSlice<'slice, Slice>);