use std::fmt;
use std::ops::{Deref, Index, IndexMut};
use std::{default::Default, usize};
use crate::unsafe_cell_type::U;
pub struct FastArray<T, const LEN: usize> {
item: U<UnsafeData<T, LEN>>,
}
impl<T, const LEN: usize> Deref for FastArray<T, LEN> {
type Target = UnsafeData<T, LEN>;
fn deref(&self) -> &Self::Target {
self.item.as_ref()
}
}
pub struct UnsafeData<T, const LEN: usize> {
items: [Option<T>; LEN],
index: usize,
pub count: usize,
}
impl<T, const LEN: usize> FastArray<T, LEN> {
pub fn new() -> Self {
let items: [Option<T>; LEN] = std::array::from_fn(|_| None);
let item = UnsafeData {
items,
index: 0,
count: 0,
};
Self { item: U::new(item) }
}
fn item_mut(&self) -> &mut UnsafeData<T, LEN> {
self.item.as_mut()
}
pub fn push(&self, item_new: T) {
let self_item = self.item_mut();
if self_item.count == 0 {
} else {
self_item.index += 1;
if self_item.index == LEN {
self_item.index = 0;
}
}
self_item.items[self.index] = Some(item_new);
self_item.count += 1;
}
pub fn current(&self) -> Option<&T> {
if self.count == 0 {
return None;
}
self.items[self.index].as_ref()
}
pub fn clear(&self) {
let self_item = self.item_mut();
self_item.index = 0;
self_item.count = 0;
}
pub fn find<F: FnMut(&T) -> bool>(&self, mut f: F) -> Option<&T> {
if self.count == 0 {
return None;
}
if let Some(当前项) = &self.items[self.index] {
if f(当前项) {
return Some(当前项);
}
}
let index_当前索引 = self.index;
for idx in (0..index_当前索引).rev() {
if let Some(item) = &self.items[idx] {
if f(item) {
return Some(item);
}
}
}
if self.count <= LEN {
return None;
}
for idx in ((index_当前索引 + 1)..self.items.len()).rev() {
if let Some(item) = &self.items[idx] {
if f(item) {
return Some(item);
}
}
}
None
}
pub fn find_vec<F: FnMut(&T) -> bool>(&self, mut f: F) -> Vec<&T> {
if self.count == 0 {
return vec![];
}
let mut r_items = vec![];
if let Some(当前项) = &self.items[self.index] {
if f(当前项) {
r_items.push(当前项);
}
}
let index_当前索引 = self.index;
for idx in (0..index_当前索引).rev() {
if let Some(item) = &self.items[idx] {
if f(item) {
r_items.push(item);
}
}
}
if self.count <= LEN {
return r_items;
}
for idx in ((index_当前索引 + 1)..self.items.len()).rev() {
if let Some(item) = &self.items[idx] {
if f(item) {
r_items.push(item);
}
}
}
r_items
}
pub fn len(&self) -> usize {
if self.count <= LEN {
self.count
} else {
LEN
}
}
pub fn is_empty(&self) -> bool {
self.count == 0
}
pub fn iter(&self) -> Iter<'_, T, LEN> {
let len = self.len();
let back = if len == 0 {
0
} else if self.count <= LEN {
0
} else {
(self.index + 1) % LEN
};
Iter {
data: self.item.as_ref(),
remaining: len,
front: self.index,
back,
}
}
fn logical_to_physical(&self, logical_idx: usize) -> usize {
assert!(
logical_idx < self.len(),
"index out of bounds: the len is {} but the index is {}",
self.len(),
logical_idx
);
if self.index >= logical_idx {
self.index - logical_idx
} else {
LEN - (logical_idx - self.index)
}
}
}
pub struct Iter<'a, T, const LEN: usize> {
data: &'a UnsafeData<T, LEN>,
remaining: usize,
front: usize,
back: usize,
}
impl<'a, T, const LEN: usize> Iterator for Iter<'a, T, LEN> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
if self.remaining == 0 {
return None;
}
let item = self.data.items[self.front].as_ref();
self.front = if self.front == 0 { LEN - 1 } else { self.front - 1 };
self.remaining -= 1;
item
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.remaining, Some(self.remaining))
}
}
impl<'a, T, const LEN: usize> DoubleEndedIterator for Iter<'a, T, LEN> {
fn next_back(&mut self) -> Option<Self::Item> {
if self.remaining == 0 {
return None;
}
let item = self.data.items[self.back].as_ref();
self.back = if self.back == LEN - 1 { 0 } else { self.back + 1 };
self.remaining -= 1;
item
}
}
impl<'a, T, const LEN: usize> ExactSizeIterator for Iter<'a, T, LEN> {}
impl<'a, T, const LEN: usize> IntoIterator for &'a FastArray<T, LEN> {
type Item = &'a T;
type IntoIter = Iter<'a, T, LEN>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
pub struct IntoIter<T, const LEN: usize> {
items: [Option<T>; LEN],
remaining: usize,
front: usize,
back: usize,
}
impl<T, const LEN: usize> Iterator for IntoIter<T, LEN> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
if self.remaining == 0 {
return None;
}
let item = self.items[self.front].take();
self.front = if self.front == 0 { LEN - 1 } else { self.front - 1 };
self.remaining -= 1;
item
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.remaining, Some(self.remaining))
}
}
impl<T, const LEN: usize> DoubleEndedIterator for IntoIter<T, LEN> {
fn next_back(&mut self) -> Option<Self::Item> {
if self.remaining == 0 {
return None;
}
let item = self.items[self.back].take();
self.back = if self.back == LEN - 1 { 0 } else { self.back + 1 };
self.remaining -= 1;
item
}
}
impl<T, const LEN: usize> ExactSizeIterator for IntoIter<T, LEN> {}
impl<T, const LEN: usize> IntoIterator for FastArray<T, LEN> {
type Item = T;
type IntoIter = IntoIter<T, LEN>;
fn into_iter(self) -> Self::IntoIter {
let len = self.len();
let index = self.index;
let count = self.count;
let items = self.item.into_inner().items;
let back = if len == 0 {
0
} else if count <= LEN {
0
} else {
(index + 1) % LEN
};
IntoIter {
items,
remaining: len,
front: index,
back,
}
}
}
impl<T: fmt::Debug, const LEN: usize> fmt::Debug for FastArray<T, LEN> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.iter()).finish()
}
}
impl<T: fmt::Display, const LEN: usize> fmt::Display for FastArray<T, LEN> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "[")?;
let mut first = true;
for item in self.iter() {
if !first {
write!(f, ", ")?;
}
write!(f, "{}", item)?;
first = false;
}
write!(f, "]")
}
}
impl<T, const LEN: usize> Index<usize> for FastArray<T, LEN> {
type Output = T;
fn index(&self, idx: usize) -> &Self::Output {
let physical = self.logical_to_physical(idx);
self.items[physical].as_ref().unwrap()
}
}
impl<T, const LEN: usize> IndexMut<usize> for FastArray<T, LEN> {
fn index_mut(&mut self, idx: usize) -> &mut Self::Output {
let physical = self.logical_to_physical(idx);
self.item.as_mut().items[physical].as_mut().unwrap()
}
}
impl<T, const LEN: usize> Default for FastArray<T, LEN> {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
fn make_cache(values: &[i32]) -> FastArray<i32, 4> {
let cache = FastArray::<i32, 4>::new();
for &v in values {
cache.push(v);
}
cache
}
#[test]
fn test_empty_no_push() {
let cache = FastArray::<i32, 4>::new();
assert_eq!(cache.len(), 0);
assert_eq!(cache.count, 0);
assert!(cache.is_empty());
assert!(cache.current().is_none());
assert!(cache.find(|_| true).is_none());
assert!(cache.find_vec(|_| true).is_empty());
assert_eq!(cache.iter().count(), 0);
let collected: Vec<&i32> = cache.iter().collect();
assert!(collected.is_empty());
}
#[test]
fn test_push_single() {
let cache = FastArray::<i32, 4>::new();
cache.push(42);
assert_eq!(cache.len(), 1);
assert_eq!(cache.count, 1);
assert!(!cache.is_empty());
assert_eq!(cache.current(), Some(&42));
assert_eq!(cache[0], 42);
let items: Vec<&i32> = cache.iter().collect();
assert_eq!(items, vec![&42]);
}
#[test]
fn test_partial_fill() {
let cache = make_cache(&[10, 20]);
assert_eq!(cache.len(), 2);
assert_eq!(cache.count, 2);
assert!(!cache.is_empty());
assert_eq!(cache.current(), Some(&20));
let items: Vec<&i32> = cache.iter().collect();
assert_eq!(items, vec![&20, &10]);
}
#[test]
fn test_partial_fill_three() {
let cache = make_cache(&[10, 20, 30]);
assert_eq!(cache.len(), 3);
assert_eq!(cache.count, 3);
assert_eq!(cache.current(), Some(&30));
let items: Vec<&i32> = cache.iter().collect();
assert_eq!(items, vec![&30, &20, &10]);
}
#[test]
fn test_exact_full() {
let cache = make_cache(&[1, 2, 3, 4]);
assert_eq!(cache.len(), 4);
assert_eq!(cache.count, 4);
assert_eq!(cache.current(), Some(&4));
let items: Vec<&i32> = cache.iter().collect();
assert_eq!(items, vec![&4, &3, &2, &1]);
}
#[test]
fn test_overflow_by_one() {
let cache = make_cache(&[1, 2, 3, 4, 5]);
assert_eq!(cache.len(), 4);
assert_eq!(cache.count, 5);
assert_eq!(cache.current(), Some(&5));
let items: Vec<&i32> = cache.iter().collect();
assert_eq!(items, vec![&5, &4, &3, &2]);
}
#[test]
fn test_overflow_by_two() {
let cache = make_cache(&[1, 2, 3, 4, 5, 6]);
assert_eq!(cache.len(), 4);
assert_eq!(cache.count, 6);
assert_eq!(cache.current(), Some(&6));
let items: Vec<&i32> = cache.iter().collect();
assert_eq!(items, vec![&6, &5, &4, &3]);
}
#[test]
fn test_many_wraps() {
let values: Vec<i32> = (1..=20).collect();
let cache = make_cache(&values);
assert_eq!(cache.len(), 4);
assert_eq!(cache.count, 20);
assert_eq!(cache.current(), Some(&20));
let items: Vec<&i32> = cache.iter().collect();
assert_eq!(items, vec![&20, &19, &18, &17]);
}
#[test]
fn test_many_wraps_large() {
let values: Vec<i32> = (1..=100).collect();
let cache = make_cache(&values);
assert_eq!(cache.len(), 4);
assert_eq!(cache.count, 100);
assert_eq!(cache.current(), Some(&100));
let items: Vec<&i32> = cache.iter().collect();
assert_eq!(items, vec![&100, &99, &98, &97]);
}
#[test]
fn test_exact_two_wraps() {
let values: Vec<i32> = (1..=8).collect();
let cache = make_cache(&values);
assert_eq!(cache.len(), 4);
assert_eq!(cache.count, 8);
let items: Vec<&i32> = cache.iter().collect();
assert_eq!(items, vec![&8, &7, &6, &5]);
}
#[test]
fn test_exact_two_wraps_plus_one() {
let values: Vec<i32> = (1..=9).collect();
let cache = make_cache(&values);
assert_eq!(cache.len(), 4);
assert_eq!(cache.count, 9);
let items: Vec<&i32> = cache.iter().collect();
assert_eq!(items, vec![&9, &8, &7, &6]);
}
#[test]
fn test_len_one_cache() {
let cache = FastArray::<i32, 1>::new();
assert!(cache.is_empty());
cache.push(1);
assert_eq!(cache.len(), 1);
assert_eq!(cache[0], 1);
cache.push(2);
assert_eq!(cache.len(), 1);
assert_eq!(cache.count, 2);
assert_eq!(cache[0], 2);
cache.push(3);
assert_eq!(cache[0], 3);
assert_eq!(cache.count, 3);
let items: Vec<&i32> = cache.iter().collect();
assert_eq!(items, vec![&3]);
}
#[test]
fn test_iter_empty() {
let cache = FastArray::<i32, 4>::new();
let mut iter = cache.iter();
assert_eq!(iter.next(), None);
}
#[test]
fn test_iter_size_hint() {
let cache = make_cache(&[1, 2, 3]);
let iter = cache.iter();
assert_eq!(iter.size_hint(), (3, Some(3)));
assert_eq!(iter.len(), 3);
}
#[test]
fn test_iter_exact_size_overflow() {
let cache = make_cache(&[1, 2, 3, 4, 5]);
let iter = cache.iter();
assert_eq!(iter.len(), 4);
}
#[test]
fn test_iter_step_by_step() {
let cache = make_cache(&[10, 20, 30]);
let mut iter = cache.iter();
assert_eq!(iter.next(), Some(&30));
assert_eq!(iter.len(), 2);
assert_eq!(iter.next(), Some(&20));
assert_eq!(iter.len(), 1);
assert_eq!(iter.next(), Some(&10));
assert_eq!(iter.len(), 0);
assert_eq!(iter.next(), None);
}
#[test]
fn test_into_iter_borrow() {
let cache = make_cache(&[10, 20, 30]);
let items: Vec<&i32> = (&cache).into_iter().collect();
assert_eq!(items, vec![&30, &20, &10]);
}
#[test]
fn test_for_loop() {
let cache = make_cache(&[1, 2, 3]);
let mut items = vec![];
for item in &cache {
items.push(*item);
}
assert_eq!(items, vec![3, 2, 1]);
}
#[test]
fn test_for_loop_overflow() {
let cache = make_cache(&[1, 2, 3, 4, 5, 6]);
let mut items = vec![];
for item in &cache {
items.push(*item);
}
assert_eq!(items, vec![6, 5, 4, 3]);
}
#[test]
fn test_len_and_count_incremental() {
let cache = FastArray::<i32, 4>::new();
assert_eq!(cache.len(), 0);
assert_eq!(cache.count, 0);
assert!(cache.is_empty());
cache.push(1);
assert_eq!(cache.len(), 1);
assert_eq!(cache.count, 1);
assert!(!cache.is_empty());
cache.push(2);
cache.push(3);
cache.push(4);
assert_eq!(cache.len(), 4);
assert_eq!(cache.count, 4);
cache.push(5);
assert_eq!(cache.len(), 4); assert_eq!(cache.count, 5);
cache.push(6);
cache.push(7);
assert_eq!(cache.len(), 4);
assert_eq!(cache.count, 7);
}
#[test]
fn test_debug_empty() {
let cache = FastArray::<i32, 4>::new();
assert_eq!(format!("{:?}", cache), "[]");
}
#[test]
fn test_debug_partial() {
let cache = make_cache(&[1, 2]);
assert_eq!(format!("{:?}", cache), "[2, 1]");
}
#[test]
fn test_debug_full() {
let cache = make_cache(&[1, 2, 3, 4]);
assert_eq!(format!("{:?}", cache), "[4, 3, 2, 1]");
}
#[test]
fn test_debug_overflow() {
let cache = make_cache(&[1, 2, 3, 4, 5, 6]);
assert_eq!(format!("{:?}", cache), "[6, 5, 4, 3]");
}
#[test]
fn test_display_empty() {
let cache = FastArray::<i32, 4>::new();
assert_eq!(format!("{}", cache), "[]");
}
#[test]
fn test_display_partial() {
let cache = make_cache(&[1, 2]);
assert_eq!(format!("{}", cache), "[2, 1]");
}
#[test]
fn test_display_full() {
let cache = make_cache(&[1, 2, 3, 4]);
assert_eq!(format!("{}", cache), "[4, 3, 2, 1]");
}
#[test]
fn test_display_overflow() {
let cache = make_cache(&[1, 2, 3, 4, 5, 6]);
assert_eq!(format!("{}", cache), "[6, 5, 4, 3]");
}
#[test]
fn test_index_partial() {
let cache = make_cache(&[10, 20, 30]);
assert_eq!(cache[0], 30); assert_eq!(cache[1], 20);
assert_eq!(cache[2], 10); }
#[test]
fn test_index_full() {
let cache = make_cache(&[1, 2, 3, 4]);
assert_eq!(cache[0], 4);
assert_eq!(cache[1], 3);
assert_eq!(cache[2], 2);
assert_eq!(cache[3], 1);
}
#[test]
fn test_index_overflow() {
let cache = make_cache(&[1, 2, 3, 4, 5, 6]);
assert_eq!(cache[0], 6);
assert_eq!(cache[1], 5);
assert_eq!(cache[2], 4);
assert_eq!(cache[3], 3);
}
#[test]
#[should_panic(expected = "index out of bounds")]
fn test_index_out_of_bounds_empty() {
let cache = FastArray::<i32, 4>::new();
let _ = cache[0];
}
#[test]
#[should_panic(expected = "index out of bounds")]
fn test_index_out_of_bounds_partial() {
let cache = make_cache(&[1, 2]);
let _ = cache[2];
}
#[test]
#[should_panic(expected = "index out of bounds")]
fn test_index_out_of_bounds_full() {
let cache = make_cache(&[1, 2, 3, 4]);
let _ = cache[4];
}
#[test]
fn test_index_mut_partial() {
let mut cache = make_cache(&[10, 20, 30]);
cache[0] = 99; assert_eq!(cache[0], 99);
assert_eq!(cache[1], 20);
assert_eq!(cache[2], 10);
cache[2] = 88; assert_eq!(cache[2], 88);
}
#[test]
fn test_index_mut_overflow() {
let mut cache = make_cache(&[1, 2, 3, 4, 5]);
cache[0] = 99; assert_eq!(cache[0], 99);
assert_eq!(cache[1], 4);
assert_eq!(cache[2], 3);
assert_eq!(cache[3], 2);
}
#[test]
fn test_index_mut_then_iter() {
let mut cache = make_cache(&[1, 2, 3, 4]);
cache[1] = 33; let items: Vec<&i32> = cache.iter().collect();
assert_eq!(items, vec![&4, &33, &2, &1]);
}
#[test]
fn test_find_empty() {
let cache = FastArray::<i32, 4>::new();
assert!(cache.find(|_| true).is_none());
}
#[test]
fn test_find_partial() {
let cache = make_cache(&[10, 20, 30]);
assert_eq!(cache.find(|&v| v >= 20), Some(&30));
assert_eq!(cache.find(|&v| v == 10), Some(&10));
assert!(cache.find(|&v| v > 100).is_none());
}
#[test]
fn test_find_full() {
let cache = make_cache(&[1, 2, 3, 4]);
assert_eq!(cache.find(|&v| v == 1), Some(&1));
assert_eq!(cache.find(|&v| v == 4), Some(&4));
assert_eq!(cache.find(|&v| v % 2 == 0), Some(&4)); }
#[test]
fn test_find_overflow() {
let cache = make_cache(&[1, 2, 3, 4, 5]);
assert!(cache.find(|&v| v == 1).is_none());
assert_eq!(cache.find(|&v| v == 5), Some(&5));
assert_eq!(cache.find(|&v| v == 2), Some(&2));
}
#[test]
fn test_find_vec_empty() {
let cache = FastArray::<i32, 4>::new();
assert!(cache.find_vec(|_| true).is_empty());
}
#[test]
fn test_find_vec_partial() {
let cache = make_cache(&[10, 20, 30]);
let found = cache.find_vec(|&v| v >= 20);
assert_eq!(found, vec![&30, &20]);
}
#[test]
fn test_find_vec_all() {
let cache = make_cache(&[1, 2, 3, 4]);
let found = cache.find_vec(|_| true);
assert_eq!(found, vec![&4, &3, &2, &1]);
}
#[test]
fn test_find_vec_overflow() {
let cache = make_cache(&[1, 2, 3, 4, 5, 6]);
let found = cache.find_vec(|_| true);
assert_eq!(found, vec![&6, &5, &4, &3]);
}
#[test]
fn test_find_vec_none_match() {
let cache = make_cache(&[1, 2, 3]);
let found = cache.find_vec(|&v| v > 100);
assert!(found.is_empty());
}
#[test]
fn test_current_empty() {
let cache = FastArray::<i32, 4>::new();
assert!(cache.current().is_none());
}
#[test]
fn test_current_after_pushes() {
let cache = FastArray::<i32, 4>::new();
cache.push(10);
assert_eq!(cache.current(), Some(&10));
cache.push(20);
assert_eq!(cache.current(), Some(&20));
cache.push(30);
cache.push(40);
cache.push(50); assert_eq!(cache.current(), Some(&50));
}
#[test]
fn test_clear() {
let cache = make_cache(&[1, 2, 3, 4]);
assert_eq!(cache.len(), 4);
cache.clear();
assert_eq!(cache.len(), 0);
assert_eq!(cache.count, 0);
assert!(cache.is_empty());
assert!(cache.current().is_none());
assert_eq!(cache.iter().count(), 0);
}
#[test]
fn test_clear_then_push() {
let cache = make_cache(&[1, 2, 3, 4, 5]);
cache.clear();
cache.push(100);
assert_eq!(cache.len(), 1);
assert_eq!(cache.count, 1);
assert_eq!(cache.current(), Some(&100));
let items: Vec<&i32> = cache.iter().collect();
assert_eq!(items, vec![&100]);
}
#[test]
fn test_clear_overflow_then_refill() {
let cache = make_cache(&[1, 2, 3, 4, 5, 6]);
cache.clear();
cache.push(100);
cache.push(200);
assert_eq!(cache.len(), 2);
assert_eq!(cache.count, 2);
let items: Vec<&i32> = cache.iter().collect();
assert_eq!(items, vec![&200, &100]);
}
#[test]
fn test_default() {
let cache: FastArray<i32, 4> = Default::default();
assert!(cache.is_empty());
assert_eq!(cache.len(), 0);
}
#[test]
fn test_iter_index_consistency() {
let cache = make_cache(&[10, 20, 30, 40, 50, 60]);
let iter_items: Vec<&i32> = cache.iter().collect();
for (i, item) in iter_items.iter().enumerate() {
assert_eq!(**item, cache[i]);
}
}
#[test]
fn test_iter_find_vec_consistency() {
let cache = make_cache(&[10, 20, 30, 40, 50, 60]);
let iter_items: Vec<&i32> = cache.iter().collect();
let find_items = cache.find_vec(|_| true);
assert_eq!(iter_items, find_items);
}
#[test]
fn test_iter_find_vec_consistency_partial() {
let cache = make_cache(&[10, 20]);
let iter_items: Vec<&i32> = cache.iter().collect();
let find_items = cache.find_vec(|_| true);
assert_eq!(iter_items, find_items);
}
#[test]
fn test_iter_find_vec_consistency_exact_full() {
let cache = make_cache(&[1, 2, 3, 4]);
let iter_items: Vec<&i32> = cache.iter().collect();
let find_items = cache.find_vec(|_| true);
assert_eq!(iter_items, find_items);
}
#[test]
fn test_iter_find_vec_consistency_many_wraps() {
let values: Vec<i32> = (1..=100).collect();
let cache = make_cache(&values);
let iter_items: Vec<&i32> = cache.iter().collect();
let find_items = cache.find_vec(|_| true);
assert_eq!(iter_items, find_items);
}
#[test]
fn test_push_clear_push_cycle() {
let cache = FastArray::<i32, 4>::new();
for i in 1..=6 {
cache.push(i);
}
assert_eq!(cache.len(), 4);
let items: Vec<&i32> = cache.iter().collect();
assert_eq!(items, vec![&6, &5, &4, &3]);
cache.clear();
assert!(cache.is_empty());
for i in 100..=102 {
cache.push(i);
}
assert_eq!(cache.len(), 3);
let items: Vec<&i32> = cache.iter().collect();
assert_eq!(items, vec![&102, &101, &100]);
cache.push(103);
cache.push(104);
assert_eq!(cache.len(), 4);
let items: Vec<&i32> = cache.iter().collect();
assert_eq!(items, vec![&104, &103, &102, &101]);
}
#[test]
fn test_display_debug_consistency() {
let cache = make_cache(&[5, 10, 15]);
let display = format!("{}", cache);
assert_eq!(display, "[15, 10, 5]");
let debug = format!("{:?}", cache);
assert_eq!(debug, "[15, 10, 5]");
}
#[test]
fn test_all_apis_on_overflow_scenario() {
let cache = make_cache(&[1, 2, 3, 4, 5, 6, 7]);
assert_eq!(cache.len(), 4);
assert_eq!(cache.count, 7);
assert!(!cache.is_empty());
assert_eq!(cache.current(), Some(&7));
let items: Vec<&i32> = cache.iter().collect();
assert_eq!(items, vec![&7, &6, &5, &4]);
let items2: Vec<&i32> = (&cache).into_iter().collect();
assert_eq!(items2, vec![&7, &6, &5, &4]);
assert_eq!(cache[0], 7);
assert_eq!(cache[1], 6);
assert_eq!(cache[2], 5);
assert_eq!(cache[3], 4);
assert_eq!(cache.find(|&v| v == 5), Some(&5));
assert!(cache.find(|&v| v == 1).is_none());
let found = cache.find_vec(|&v| v >= 6);
assert_eq!(found, vec![&7, &6]);
assert_eq!(format!("{:?}", cache), "[7, 6, 5, 4]");
assert_eq!(format!("{}", cache), "[7, 6, 5, 4]");
}
#[test]
fn test_rev_empty() {
let cache = FastArray::<i32, 4>::new();
let items: Vec<&i32> = cache.iter().rev().collect();
assert!(items.is_empty());
}
#[test]
fn test_rev_single() {
let cache = make_cache(&[42]);
let items: Vec<&i32> = cache.iter().rev().collect();
assert_eq!(items, vec![&42]);
}
#[test]
fn test_rev_partial() {
let cache = make_cache(&[10, 20, 30]);
let items: Vec<&i32> = cache.iter().rev().collect();
assert_eq!(items, vec![&10, &20, &30]);
}
#[test]
fn test_rev_exact_full() {
let cache = make_cache(&[1, 2, 3, 4]);
let items: Vec<&i32> = cache.iter().rev().collect();
assert_eq!(items, vec![&1, &2, &3, &4]);
}
#[test]
fn test_rev_overflow() {
let cache = make_cache(&[1, 2, 3, 4, 5, 6]);
let items: Vec<&i32> = cache.iter().rev().collect();
assert_eq!(items, vec![&3, &4, &5, &6]);
}
#[test]
fn test_rev_many_wraps() {
let values: Vec<i32> = (1..=20).collect();
let cache = make_cache(&values);
let items: Vec<&i32> = cache.iter().rev().collect();
assert_eq!(items, vec![&17, &18, &19, &20]);
}
#[test]
fn test_rev_len_one_cache() {
let cache = FastArray::<i32, 1>::new();
cache.push(1);
cache.push(2);
cache.push(3);
let items: Vec<&i32> = cache.iter().rev().collect();
assert_eq!(items, vec![&3]);
}
#[test]
fn test_rev_is_inverse_of_iter() {
let cache = make_cache(&[1, 2, 3, 4, 5, 6, 7]);
let forward: Vec<&i32> = cache.iter().collect();
let mut backward: Vec<&i32> = cache.iter().rev().collect();
backward.reverse();
assert_eq!(forward, backward);
}
#[test]
fn test_mixed_next_and_next_back() {
let cache = make_cache(&[1, 2, 3, 4]);
let mut iter = cache.iter();
assert_eq!(iter.next(), Some(&4));
assert_eq!(iter.next_back(), Some(&1));
assert_eq!(iter.next(), Some(&3));
assert_eq!(iter.next_back(), Some(&2));
assert_eq!(iter.next(), None);
assert_eq!(iter.next_back(), None);
}
#[test]
fn test_into_iter_owned_empty() {
let cache = FastArray::<i32, 4>::new();
let items: Vec<i32> = cache.into_iter().collect();
assert!(items.is_empty());
}
#[test]
fn test_into_iter_owned_partial() {
let cache = make_cache(&[10, 20, 30]);
let items: Vec<i32> = cache.into_iter().collect();
assert_eq!(items, vec![30, 20, 10]);
}
#[test]
fn test_into_iter_owned_full() {
let cache = make_cache(&[1, 2, 3, 4]);
let items: Vec<i32> = cache.into_iter().collect();
assert_eq!(items, vec![4, 3, 2, 1]);
}
#[test]
fn test_into_iter_owned_overflow() {
let cache = make_cache(&[1, 2, 3, 4, 5, 6]);
let items: Vec<i32> = cache.into_iter().collect();
assert_eq!(items, vec![6, 5, 4, 3]);
}
#[test]
fn test_into_iter_owned_rev() {
let cache = make_cache(&[1, 2, 3, 4, 5]);
let items: Vec<i32> = cache.into_iter().rev().collect();
assert_eq!(items, vec![2, 3, 4, 5]);
}
#[test]
fn test_into_iter_owned_for_loop() {
let cache = make_cache(&[10, 20, 30]);
let mut items = vec![];
for item in cache {
items.push(item);
}
assert_eq!(items, vec![30, 20, 10]);
}
#[test]
fn test_into_iter_owned_mixed() {
let cache = make_cache(&[1, 2, 3, 4]);
let mut iter = cache.into_iter();
assert_eq!(iter.next(), Some(4));
assert_eq!(iter.next_back(), Some(1));
assert_eq!(iter.len(), 2);
assert_eq!(iter.next(), Some(3));
assert_eq!(iter.next_back(), Some(2));
assert_eq!(iter.next(), None);
}
}