use std::collections::VecDeque;
use std::ops::{Index, IndexMut};
use std::slice::Iter;
use std::vec::IntoIter;
use crate::data::atomic::Word;
use crate::data::identification::{Address, Area, Cursor, Identifier};
pub trait ProduceConsume<T> {
fn produce(&mut self, data: T);
fn consume(&mut self) -> Option<T>;
fn len(&self) -> usize;
fn is_empty(&self) -> bool;
}
#[derive(Clone, Debug, Default)]
pub struct Array {
data: Vec<Word>,
}
impl Array {
pub fn new(size: usize) -> Self {
let mut array = Self { data: Vec::new() };
array.data.resize(size, Word::default());
array
}
pub fn from(arr: &[Word]) -> Self {
Self { data: arr.to_vec() }
}
pub fn sub(&self, ignore_start: Address, ignore_end: Address) -> Self {
Self::from(&self.as_slice()[ignore_start.to_usize()..(self.len() - ignore_end.to_usize())])
}
pub fn sub_from_start(&self, ignore_end: Address) -> Self { self.sub(Address::default(), ignore_end) }
pub fn sub_from_end(&self, ignore_start: Address) -> Self { self.sub(ignore_start, Address::default()) }
pub fn split(&self, cesure: Address) -> (Array, Array) {
let mut first = Array::new(0);
let mut second = Array::new(0);
let mut index = Address::default();
while let Some(word) = self.next(&mut index) {
if index < cesure {
first.push(word);
} else {
second.push(word);
}
}
(first, second)
}
pub fn as_slice(&self) -> &[Word] { &self.data }
pub fn as_mut_slice(&mut self) -> &mut [Word] { &mut self.data }
pub fn next(&self, index: &mut Address) -> Option<Word> {
let output = self.data.get(index.to_usize()).cloned();
index.increment();
output
}
pub fn iter(&self) -> Iter<Word> { self.data.iter() }
pub fn len(&self) -> usize { self.data.len() }
pub fn is_empty(&self) -> bool { self.data.is_empty() }
pub fn push(&mut self, value: Word) { self.data.push(value); }
pub fn insert(&mut self, address: Address, value: Word) { self.data.insert(address.to_usize(), value); }
pub fn remove(&mut self, index: Address) -> Word { self.data.remove(index.to_usize()) }
pub fn merge(&mut self, with: &Array) {
self.data.extend_from_slice(with.as_slice());
}
pub fn extract(&self, area: Area) -> Array { self.sub(area.start(), area.end()) }
pub fn extract_word(&self, area: Area, cursor: Address) -> Word { self[area.constraint(cursor)] }
pub fn next_word(&self, cursor: Cursor) -> (Word, Cursor) {
let data = self[cursor.area.constraint(cursor.pointer)];
let cursor = Cursor { area: cursor.area, pointer: cursor.next() };
(data, cursor)
}
}
impl IntoIterator for Array {
type Item = Word;
type IntoIter = IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter { self.data.into_iter() }
}
impl Index<Address> for Array {
type Output = Word;
fn index(&self, index: Address) -> &Self::Output { &self.data[index.to_usize()] }
}
impl IndexMut<Address> for Array {
fn index_mut(&mut self, index: Address) -> &mut Self::Output { &mut self.data[index.to_usize()] }
}
#[derive(Clone, Debug, Default)]
pub struct WordQueue {
raw: VecDeque<Word>,
}
impl WordQueue {
pub fn new() -> Self { Self::default() }
}
impl ProduceConsume<Word> for WordQueue {
fn produce(&mut self, word: Word) { self.raw.push_back(word); }
fn consume(&mut self) -> Option<Word> { self.raw.pop_front() }
fn len(&self) -> usize { self.raw.len() }
fn is_empty(&self) -> bool { self.len() == 0 }
}
#[derive(Clone, Debug, Default)]
pub struct WordStack {
raw: Vec<Word>,
}
impl WordStack {
pub fn new() -> Self { Self::default() }
}
impl ProduceConsume<Word> for WordStack {
fn produce(&mut self, word: Word) { self.raw.push(word); }
fn consume(&mut self) -> Option<Word> { self.raw.pop() }
fn len(&self) -> usize { self.raw.len() }
fn is_empty(&self) -> bool { self.len() == 0 }
}