use std::cmp::{max, min};
use std::ops::{Index, IndexMut};
use std::ops::{Range, RangeFrom, RangeFull, RangeTo, RangeToInclusive};
use std::slice;
use crate::index::Column;
#[derive(Default, Clone, Debug)]
pub struct Row<T> {
inner: Vec<T>,
pub(crate) occ: usize,
}
impl<T: PartialEq> PartialEq for Row<T> {
fn eq(&self, other: &Self) -> bool {
self.inner == other.inner
}
}
impl<T: Copy + Clone> Row<T> {
pub fn new(columns: Column, template: &T) -> Self {
Self {
inner: vec![*template; *columns],
occ: 0,
}
}
pub fn grow(&mut self, cols: Column, template: &T) {
assert!(self.len() < *cols);
while self.len() != *cols {
self.inner.push(*template);
}
}
#[inline(never)]
pub fn reset(&mut self, other: &T) {
let occ = self.occ;
for item in &mut self.inner[..occ] {
*item = *other;
}
self.occ = 0;
}
}
#[allow(clippy::len_without_is_empty)]
impl<T> Row<T> {
pub fn shrink(&mut self, cols: Column) {
while self.len() != *cols {
self.inner.pop();
}
self.occ = min(self.occ, *cols);
}
pub fn len(&self) -> usize {
self.inner.len()
}
pub fn iter(&self) -> slice::Iter<'_, T> {
self.inner.iter()
}
}
impl<'a, T> IntoIterator for &'a Row<T> {
type Item = &'a T;
type IntoIter = slice::Iter<'a, T>;
#[inline]
fn into_iter(self) -> slice::Iter<'a, T> {
self.iter()
}
}
impl<'a, T> IntoIterator for &'a mut Row<T> {
type Item = &'a mut T;
type IntoIter = slice::IterMut<'a, T>;
#[inline]
fn into_iter(self) -> slice::IterMut<'a, T> {
self.occ = self.len();
self.inner.iter_mut()
}
}
impl<T> Index<Column> for Row<T> {
type Output = T;
#[inline]
fn index(&self, index: Column) -> &T {
&self.inner[index.0]
}
}
impl<T> IndexMut<Column> for Row<T> {
#[inline]
fn index_mut(&mut self, index: Column) -> &mut T {
self.occ = max(self.occ, *index + 1);
&mut self.inner[index.0]
}
}
impl<T> Index<Range<Column>> for Row<T> {
type Output = [T];
#[inline]
fn index(&self, index: Range<Column>) -> &[T] {
&self.inner[(index.start.0)..(index.end.0)]
}
}
impl<T> IndexMut<Range<Column>> for Row<T> {
#[inline]
fn index_mut(&mut self, index: Range<Column>) -> &mut [T] {
self.occ = max(self.occ, *index.end);
&mut self.inner[(index.start.0)..(index.end.0)]
}
}
impl<T> Index<RangeTo<Column>> for Row<T> {
type Output = [T];
#[inline]
fn index(&self, index: RangeTo<Column>) -> &[T] {
&self.inner[..(index.end.0)]
}
}
impl<T> IndexMut<RangeTo<Column>> for Row<T> {
#[inline]
fn index_mut(&mut self, index: RangeTo<Column>) -> &mut [T] {
self.occ = max(self.occ, *index.end);
&mut self.inner[..(index.end.0)]
}
}
impl<T> Index<RangeFrom<Column>> for Row<T> {
type Output = [T];
#[inline]
fn index(&self, index: RangeFrom<Column>) -> &[T] {
&self.inner[(index.start.0)..]
}
}
impl<T> IndexMut<RangeFrom<Column>> for Row<T> {
#[inline]
fn index_mut(&mut self, index: RangeFrom<Column>) -> &mut [T] {
self.occ = self.len();
&mut self.inner[(index.start.0)..]
}
}
impl<T> Index<RangeFull> for Row<T> {
type Output = [T];
#[inline]
fn index(&self, _: RangeFull) -> &[T] {
&self.inner[..]
}
}
impl<T> IndexMut<RangeFull> for Row<T> {
#[inline]
fn index_mut(&mut self, _: RangeFull) -> &mut [T] {
self.occ = self.len();
&mut self.inner[..]
}
}
impl<T> Index<RangeToInclusive<Column>> for Row<T> {
type Output = [T];
#[inline]
fn index(&self, index: RangeToInclusive<Column>) -> &[T] {
&self.inner[..=(index.end.0)]
}
}
impl<T> IndexMut<RangeToInclusive<Column>> for Row<T> {
#[inline]
fn index_mut(&mut self, index: RangeToInclusive<Column>) -> &mut [T] {
self.occ = max(self.occ, *index.end);
&mut self.inner[..=(index.end.0)]
}
}