use crate::cache::*;
use std::cmp::Eq;
use std::fmt;
use std::hash::Hash;
use std::iter::DoubleEndedIterator;
use std::iter::FusedIterator;
use std::marker::PhantomData;
pub struct Iter<'a, K, V>
where
K: Eq + Hash,
{
pub(crate) done: usize,
pub(crate) len: usize,
pub(crate) forward: *const Node<K, V>,
pub(crate) backward: *const Node<K, V>,
pub(crate) phantom: PhantomData<&'a (K, V)>,
}
impl<K, V> fmt::Debug for Iter<'_, K, V>
where
K: Eq + Hash + fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.done >= self.len {
write!(f, "Iter {{ done: {:?}, len: {:?} }}", self.done, self.len)
} else {
let forward = unsafe { &(*(*self.forward).key.as_ptr()) };
let backward = unsafe { &(*(*self.backward).key.as_ptr()) };
write!(
f,
"Iter {{ done: {:?}, len: {:?}, next: {:?}, next_back: {:?} }}",
self.done, self.len, backward, forward
)
}
}
}
impl<K, V> fmt::Display for Iter<'_, K, V>
where
K: Eq + Hash + fmt::Display,
V: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.done >= self.len {
write!(f, "{}/{}", self.done, self.len)
} else {
let forward = unsafe { &(*(*self.forward).key.as_ptr()) };
let backward = unsafe { &(*(*self.backward).key.as_ptr()) };
write!(
f,
"{}/{}, next: {}, next_back: {}",
self.done, self.len, backward, forward
)
}
}
}
impl<'a, K, V> Iterator for Iter<'a, K, V>
where
K: Hash + Eq,
{
type Item = (&'a K, &'a V);
fn next(&mut self) -> Option<(&'a K, &'a V)> {
if self.done >= self.len {
return None;
}
let k = unsafe { &(*(*self.backward).key.as_ptr()) as &K };
let v = unsafe { &(*(*self.backward).value.as_ptr()) as &V };
self.done += 1;
self.backward = unsafe { (*self.backward).prev };
Some((k, v))
}
fn size_hint(&self) -> (usize, Option<usize>) {
if self.done >= self.len {
let remaining = self.len - self.done;
(remaining, Some(remaining))
} else {
(0, Some(0))
}
}
}
impl<'a, K, V> DoubleEndedIterator for Iter<'a, K, V>
where
K: Hash + Eq,
{
fn next_back(&mut self) -> Option<(&'a K, &'a V)> {
if self.done >= self.len {
return None;
}
let k = unsafe { &(*(*self.forward).key.as_ptr()) as &K };
let v = unsafe { &(*(*self.forward).value.as_ptr()) as &V };
self.done += 1;
self.forward = unsafe { (*self.forward).next };
Some((k, v))
}
}
impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> where K: Eq + Hash {}
impl<'a, K, V> FusedIterator for Iter<'a, K, V> where K: Eq + Hash {}
impl<'a, K, V> Iter<'a, K, V>
where
K: Hash + Eq,
{
pub fn keys(self) -> Keys<'a, K, V> {
Keys { iter: self }
}
pub fn values(self) -> Values<'a, K, V> {
Values { iter: self }
}
}
pub struct IterMut<'a, K, V>
where
K: Eq + Hash,
{
pub(crate) done: usize,
pub(crate) len: usize,
pub(crate) forward: *mut Node<K, V>,
pub(crate) backward: *mut Node<K, V>,
pub(crate) phantom: PhantomData<&'a (K, V)>,
}
impl<K, V> fmt::Debug for IterMut<'_, K, V>
where
K: Eq + Hash + fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.done >= self.len {
write!(f, "Iter {{ done: {:?}, len: {:?} }}", self.done, self.len)
} else {
let forward = unsafe { &(*(*self.forward).key.as_ptr()) };
let backward = unsafe { &(*(*self.backward).key.as_ptr()) };
write!(
f,
"Iter {{ done: {:?}, len: {:?}, next: {:?}, next_back: {:?} }}",
self.done, self.len, backward, forward
)
}
}
}
impl<K, V> fmt::Display for IterMut<'_, K, V>
where
K: Eq + Hash + fmt::Display,
V: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.done >= self.len {
write!(f, "{}/{}", self.done, self.len)
} else {
let forward = unsafe { &(*(*self.forward).key.as_ptr()) };
let backward = unsafe { &(*(*self.backward).key.as_ptr()) };
write!(
f,
"{}/{}, next: {}, next_back: {}",
self.done, self.len, backward, forward
)
}
}
}
impl<'a, K, V> Iterator for IterMut<'a, K, V>
where
K: Hash + Eq,
{
type Item = (&'a K, &'a mut V);
fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
if self.done >= self.len {
return None;
}
let k = unsafe { &(*(*self.backward).key.as_ptr()) as &K };
let v = unsafe { &mut (*(*self.backward).value.as_mut_ptr()) as &mut V };
self.done += 1;
self.backward = unsafe { (*self.backward).prev };
Some((k, v))
}
fn size_hint(&self) -> (usize, Option<usize>) {
if self.done >= self.len {
let remaining = self.len - self.done;
(remaining, Some(remaining))
} else {
(0, Some(0))
}
}
}
impl<'a, K, V> DoubleEndedIterator for IterMut<'a, K, V>
where
K: Hash + Eq,
{
fn next_back(&mut self) -> Option<(&'a K, &'a mut V)> {
if self.done >= self.len {
return None;
}
let k = unsafe { &(*(*self.forward).key.as_ptr()) as &K };
let v = unsafe { &mut (*(*self.forward).value.as_mut_ptr()) as &mut V };
self.done += 1;
self.forward = unsafe { (*self.forward).next };
Some((k, v))
}
}
impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> where K: Eq + Hash {}
impl<'a, K, V> FusedIterator for IterMut<'a, K, V> where K: Eq + Hash {}
#[derive(Debug)]
pub struct Keys<'a, K, V>
where
K: Eq + Hash,
{
iter: Iter<'a, K, V>,
}
impl<K, V> fmt::Display for Keys<'_, K, V>
where
K: Clone + Eq + Hash + fmt::Display,
V: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.iter)
}
}
impl<'a, K, V> Iterator for Keys<'a, K, V>
where
K: Hash + Eq,
{
type Item = &'a K;
fn next(&mut self) -> Option<&'a K> {
match self.iter.next() {
Some(kv) => Some(kv.0),
None => None,
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<'a, K, V> DoubleEndedIterator for Keys<'a, K, V>
where
K: Hash + Eq,
{
fn next_back(&mut self) -> Option<&'a K> {
match self.iter.next_back() {
Some(kv) => Some(kv.0),
None => None,
}
}
}
impl<'a, K, V> ExactSizeIterator for Keys<'a, K, V> where K: Eq + Hash {}
impl<'a, K, V> FusedIterator for Keys<'a, K, V> where K: Eq + Hash {}
#[derive(Debug)]
pub struct Values<'a, K, V>
where
K: Eq + Hash,
{
iter: Iter<'a, K, V>,
}
impl<K, V> fmt::Display for Values<'_, K, V>
where
K: Clone + Eq + Hash + fmt::Display,
V: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.iter)
}
}
impl<'a, K, V> Iterator for Values<'a, K, V>
where
K: Hash + Eq,
{
type Item = &'a V;
fn next(&mut self) -> Option<&'a V> {
match self.iter.next() {
Some(kv) => Some(kv.1),
None => None,
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<'a, K, V> DoubleEndedIterator for Values<'a, K, V>
where
K: Hash + Eq,
{
fn next_back(&mut self) -> Option<&'a V> {
match self.iter.next_back() {
Some(kv) => Some(kv.1),
None => None,
}
}
}
impl<'a, K, V> ExactSizeIterator for Values<'a, K, V> where K: Eq + Hash {}
impl<'a, K, V> FusedIterator for Values<'a, K, V> where K: Eq + Hash {}
#[derive(Debug)]
pub struct IntoIter<K, V>
where
K: Eq + Hash,
{
pub(crate) len: usize,
pub(crate) cache: Cache<K, V>,
}
impl<K, V> fmt::Display for IntoIter<K, V>
where
K: Eq + Hash + fmt::Display,
V: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}/{}", self.len - self.cache.len(), self.len)
}
}
impl<K, V> Iterator for IntoIter<K, V>
where
K: Hash + Eq,
{
type Item = (K, V);
fn next(&mut self) -> Option<(K, V)> {
self.cache.pop_lru()
}
fn size_hint(&self) -> (usize, Option<usize>) {
let size = self.len - self.cache.len();
(size, Some(size))
}
}
impl<K, V> DoubleEndedIterator for IntoIter<K, V>
where
K: Hash + Eq,
{
fn next_back(&mut self) -> Option<(K, V)> {
self.cache.pop_mru()
}
}
impl<K, V> ExactSizeIterator for IntoIter<K, V> where K: Eq + Hash {}
impl<K, V> FusedIterator for IntoIter<K, V> where K: Eq + Hash {}
impl<K, V> IntoIter<K, V>
where
K: Hash + Eq,
{
pub fn keys(self) -> IntoKeys<K, V> {
IntoKeys { into_iter: self }
}
pub fn values(self) -> IntoValues<K, V> {
IntoValues { into_iter: self }
}
}
#[derive(Debug)]
pub struct IntoKeys<K, V>
where
K: Eq + Hash,
{
into_iter: IntoIter<K, V>,
}
impl<K, V> fmt::Display for IntoKeys<K, V>
where
K: Clone + Eq + Hash + fmt::Display,
V: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.into_iter)
}
}
impl<K, V> Iterator for IntoKeys<K, V>
where
K: Hash + Eq,
{
type Item = K;
fn next(&mut self) -> Option<K> {
match self.into_iter.next() {
Some(kv) => Some(kv.0),
None => None,
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.into_iter.size_hint()
}
}
impl<K, V> DoubleEndedIterator for IntoKeys<K, V>
where
K: Hash + Eq,
{
fn next_back(&mut self) -> Option<K> {
match self.into_iter.next_back() {
Some(kv) => Some(kv.0),
None => None,
}
}
}
impl<K, V> ExactSizeIterator for IntoKeys<K, V> where K: Eq + Hash {}
impl<K, V> FusedIterator for IntoKeys<K, V> where K: Eq + Hash {}
#[derive(Debug)]
pub struct IntoValues<K, V>
where
K: Eq + Hash,
{
into_iter: IntoIter<K, V>,
}
impl<K, V> fmt::Display for IntoValues<K, V>
where
K: Clone + Eq + Hash + fmt::Display,
V: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.into_iter)
}
}
impl<K, V> Iterator for IntoValues<K, V>
where
K: Hash + Eq,
{
type Item = V;
fn next(&mut self) -> Option<V> {
match self.into_iter.next() {
Some(kv) => Some(kv.1),
None => None,
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.into_iter.size_hint()
}
}
impl<K, V> DoubleEndedIterator for IntoValues<K, V>
where
K: Hash + Eq,
{
fn next_back(&mut self) -> Option<V> {
match self.into_iter.next_back() {
Some(kv) => Some(kv.1),
None => None,
}
}
}
impl<K, V> ExactSizeIterator for IntoValues<K, V> where K: Eq + Hash {}
impl<K, V> FusedIterator for IntoValues<K, V> where K: Eq + Hash {}
#[cfg(test)]
mod tests {
#[test]
fn test_iter() {
let mut cache = super::Cache::<i32, &str>::new(7);
let mut iter = cache.iter();
assert_eq!(None, iter.next());
assert_eq!(None, cache.insert(1, "one"));
assert_eq!(None, cache.insert(2, "two"));
assert_eq!(None, cache.insert(3, "three"));
assert_eq!(None, cache.insert(4, "four"));
assert_eq!(None, cache.insert(5, "five"));
assert_eq!(None, cache.insert(6, "six"));
let mut iter = cache.iter();
assert_eq!(
"0/6, next: 1, next_back: 6".to_string(),
format!("{}", &iter)
);
let mut expected: (&i32, &&str) = (&1, &"one");
assert_eq!(Some(expected), iter.next());
assert_eq!(
"1/6, next: 2, next_back: 6".to_string(),
format!("{}", &iter)
);
expected = (&2, &"two");
assert_eq!(Some(expected), iter.next());
assert_eq!(
"2/6, next: 3, next_back: 6".to_string(),
format!("{}", &iter)
);
expected = (&3, &"three");
assert_eq!(Some(expected), iter.next());
assert_eq!(
"3/6, next: 4, next_back: 6".to_string(),
format!("{}", &iter)
);
expected = (&4, &"four");
assert_eq!(Some(expected), iter.next());
assert_eq!(
"4/6, next: 5, next_back: 6".to_string(),
format!("{}", &iter)
);
expected = (&6, &"six");
assert_eq!(Some(expected), iter.next_back());
assert_eq!(
"5/6, next: 5, next_back: 5".to_string(),
format!("{}", &iter)
);
expected = (&5, &"five");
assert_eq!(Some(expected), iter.next_back());
assert_eq!("6/6".to_string(), format!("{}", &iter));
assert_eq!(None, iter.next());
}
#[test]
fn test_into_iter() {
let mut cache = super::Cache::<i32, &str>::new(7);
let mut iter = cache.iter();
assert_eq!(None, iter.next());
assert_eq!(None, cache.insert(1, "one"));
assert_eq!(None, cache.insert(2, "two"));
assert_eq!(None, cache.insert(3, "three"));
assert_eq!(None, cache.insert(4, "four"));
assert_eq!(None, cache.insert(5, "five"));
assert_eq!(None, cache.insert(6, "six"));
let mut iter = cache.into_iter();
assert_eq!("0/6".to_string(), format!("{}", &iter));
let mut expected: (i32, &str) = (1, "one");
assert_eq!(Some(expected), iter.next());
assert_eq!("1/6".to_string(), format!("{}", &iter));
expected = (2, "two");
assert_eq!(Some(expected), iter.next());
assert_eq!("2/6".to_string(), format!("{}", &iter));
expected = (3, "three");
assert_eq!(Some(expected), iter.next());
assert_eq!("3/6".to_string(), format!("{}", &iter));
expected = (4, "four");
assert_eq!(Some(expected), iter.next());
assert_eq!("4/6".to_string(), format!("{}", &iter));
expected = (5, "five");
assert_eq!(Some(expected), iter.next());
assert_eq!("5/6".to_string(), format!("{}", &iter));
expected = (6, "six");
assert_eq!(Some(expected), iter.next());
assert_eq!("6/6".to_string(), format!("{}", &iter));
assert_eq!(None, iter.next());
}
}