Skip to content

Commit

Permalink
#5 iterators
Browse files Browse the repository at this point in the history
  • Loading branch information
yegor256 committed Apr 17, 2023
1 parent 5e0af3d commit 88570fc
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 98 deletions.
123 changes: 123 additions & 0 deletions src/iterators.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// Copyright (c) 2023 Yegor Bugayenko
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

use crate::{IntoIter, Iter, Map};

impl<'a, K: Clone, V: Clone, const N: usize> Iterator for Iter<'a, K, V, N> {
type Item = (&'a K, &'a V);

#[inline]
#[must_use]
fn next(&mut self) -> Option<Self::Item> {
while self.pos < N {
if self.next <= self.pos {
break;
}
if let Present(p) = &self.pairs[self.pos] {
self.pos += 1;
return Some((&p.0, &p.1));
}
self.pos += 1;
}
None
}
}

impl<'a, K: Clone, V: Clone, const N: usize> Iterator for IntoIter<'a, K, V, N> {
type Item = (K, V);

#[inline]
#[must_use]
fn next(&mut self) -> Option<Self::Item> {
while self.pos < N {
if self.next <= self.pos {
break;
}
if self.pairs[self.pos].is_some() {
let pair = self.pairs[self.pos].clone().unwrap();
self.pos += 1;
return Some(pair);
}
self.pos += 1;
}
None
}
}

impl<'a, K: Copy + PartialEq, V: Clone + Copy, const N: usize> IntoIterator for &'a Map<K, V, N> {
type Item = (K, V);
type IntoIter = IntoIter<'a, K, V, N>;

#[inline]
fn into_iter(self) -> Self::IntoIter {
IntoIter {
next: self.next,
pos: 0,
pairs: &self.pairs,
}
}
}

use crate::Pair::Present;
#[cfg(test)]
use anyhow::Result;

#[test]
fn empty_iterator() -> Result<()> {
let m: Map<u32, u32, 4> = Map::new();
assert!(m.into_iter().next().is_none());
Ok(())
}

#[test]
fn insert_and_jump_over_next() -> Result<()> {
let mut m: Map<&str, i32, 10> = Map::new();
m.insert("foo", 42);
let mut iter = m.into_iter();
assert_eq!(42, iter.next().unwrap().1);
assert!(iter.next().is_none());
Ok(())
}

#[test]
fn insert_and_iterate() -> Result<()> {
let mut m: Map<&str, i32, 10> = Map::new();
m.insert("one", 42);
m.insert("two", 16);
let mut sum = 0;
for (_k, v) in m.iter() {
sum += v;
}
assert_eq!(58, sum);
Ok(())
}

#[test]
fn insert_and_into_iterate() -> Result<()> {
let mut m: Map<&str, i32, 10> = Map::new();
m.insert("one", 42);
m.insert("two", 16);
let mut sum = 0;
for (_k, v) in m.into_iter() {
sum += v;
}
assert_eq!(58, sum);
Ok(())
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#![allow(clippy::multiple_inherent_impl)]
#![allow(clippy::multiple_crate_versions)]

mod iterators;
mod map;
mod pair;
mod serialization;
Expand Down
98 changes: 0 additions & 98 deletions src/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,61 +21,6 @@
use crate::Pair::{Absent, Present};
use crate::{IntoIter, Iter, Map, Pair};

impl<'a, K: Clone, V: Clone, const N: usize> Iterator for Iter<'a, K, V, N> {
type Item = (&'a K, &'a V);

#[inline]
#[must_use]
fn next(&mut self) -> Option<Self::Item> {
while self.pos < N {
if self.next <= self.pos {
break;
}
if let Present(p) = &self.pairs[self.pos] {
self.pos += 1;
return Some((&p.0, &p.1));
}
self.pos += 1;
}
None
}
}

impl<'a, K: Clone, V: Clone, const N: usize> Iterator for IntoIter<'a, K, V, N> {
type Item = (K, V);

#[inline]
#[must_use]
fn next(&mut self) -> Option<Self::Item> {
while self.pos < N {
if self.next <= self.pos {
break;
}
if self.pairs[self.pos].is_some() {
let pair = self.pairs[self.pos].clone().unwrap();
self.pos += 1;
return Some(pair);
}
self.pos += 1;
}
None
}
}

impl<'a, K: Copy + PartialEq, V: Clone + Copy, const N: usize> IntoIterator for &'a Map<K, V, N> {
type Item = (K, V);
type IntoIter = IntoIter<'a, K, V, N>;

#[inline]
fn into_iter(self) -> Self::IntoIter {
IntoIter {
next: self.next,
pos: 0,
pairs: &self.pairs,
}
}
}

impl<K: Copy + PartialEq, V: Clone + Copy, const N: usize> Default for Map<K, V, N> {
fn default() -> Self {
Self::new()
Expand Down Expand Up @@ -259,49 +204,6 @@ fn empty_length() -> Result<()> {
Ok(())
}

#[test]
fn empty_iterator() -> Result<()> {
let m: Map<u32, u32, 4> = Map::new();
assert!(m.into_iter().next().is_none());
Ok(())
}

#[test]
fn insert_and_jump_over_next() -> Result<()> {
let mut m: Map<&str, i32, 10> = Map::new();
m.insert("foo", 42);
let mut iter = m.into_iter();
assert_eq!(42, iter.next().unwrap().1);
assert!(iter.next().is_none());
Ok(())
}

#[test]
fn insert_and_iterate() -> Result<()> {
let mut m: Map<&str, i32, 10> = Map::new();
m.insert("one", 42);
m.insert("two", 16);
let mut sum = 0;
for (_k, v) in m.iter() {
sum += v;
}
assert_eq!(58, sum);
Ok(())
}

#[test]
fn insert_and_into_iterate() -> Result<()> {
let mut m: Map<&str, i32, 10> = Map::new();
m.insert("one", 42);
m.insert("two", 16);
let mut sum = 0;
for (_k, v) in m.into_iter() {
sum += v;
}
assert_eq!(58, sum);
Ok(())
}

#[test]
fn insert_and_gets() -> Result<()> {
let mut m: Map<&str, i32, 10> = Map::new();
Expand Down

0 comments on commit 88570fc

Please sign in to comment.