Created
October 31, 2022 14:56
-
-
Save mo-xiaoming/b027670d5fe87341cd28593d27aeabe6 to your computer and use it in GitHub Desktop.
Rust iterator for user defined type
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![allow(dead_code, unused)] | |
#[derive(Debug, Default, Clone, std::hash::Hash, PartialEq, Eq, PartialOrd, Ord)] | |
struct Pair { | |
first: i32, | |
second: i32, | |
} | |
impl Pair { | |
fn new(first: i32, second: i32) -> Self { | |
Self { first, second} | |
} | |
fn iter(&self) -> Iter { | |
Iter {pair: self, idx: 0} | |
} | |
fn iter_mut(&mut self) -> std::iter::Chain<std::iter::Once<&mut i32>, std::iter::Once<&mut i32>> { | |
use std::iter::once; | |
once(&mut self.first).chain(once(&mut self.second)) | |
} | |
} | |
impl IntoIterator for Pair { | |
type Item = i32; | |
type IntoIter = IntoIter; | |
fn into_iter(self) -> Self::IntoIter { | |
IntoIter { pair: self, idx : 0} | |
} | |
} | |
struct IntoIter { | |
pair: Pair, | |
idx: usize, | |
} | |
impl Iterator for IntoIter { | |
type Item = i32; | |
fn next(&mut self) -> Option<Self::Item> { | |
let r = match self.idx { | |
0 => self.pair.first, | |
1 => self.pair.second, | |
_ => return None | |
}; | |
self.idx += 1; | |
Some(r) | |
} | |
} | |
impl<'a> IntoIterator for &'a Pair { | |
type Item = &'a i32; | |
type IntoIter = Iter<'a>; | |
fn into_iter(self) -> Self::IntoIter { | |
Iter{ pair: self, idx : 0} } | |
} | |
struct Iter<'a> { | |
pair: &'a Pair, | |
idx: usize, | |
} | |
impl<'a> Iterator for Iter<'a> { | |
type Item = &'a i32; | |
fn next(&mut self) -> Option<Self::Item> { | |
let r = match self.idx { | |
0 => &self.pair.first, | |
1 => &self.pair.second, | |
_ => return None | |
}; | |
self.idx += 1; | |
Some(r) | |
} | |
} | |
impl<'a> IntoIterator for &'a mut Pair { | |
type Item = &'a mut i32; | |
type IntoIter = std::iter::Chain<std::iter::Once<&'a mut i32>, std::iter::Once<&'a mut i32>>; | |
fn into_iter(self) -> Self::IntoIter { | |
self.iter_mut() | |
} | |
} | |
#[cfg(test)] | |
mod test { | |
use super::*; | |
fn good_citizen<T>(_: T) where T: std::fmt::Debug + Default + Clone + std::hash::Hash + PartialEq + PartialOrd + Eq + Ord + Send + Sync {} | |
#[test] | |
fn being_good_citizen() { good_citizen(Pair::new(0, 0)) } | |
#[test] | |
fn user_defined() { | |
let pair = Pair::new(1, 2); | |
for i in pair { let _ = i; } | |
let pair = Pair::new(1, 2); | |
for i in pair.into_iter() { let _ = i; } | |
let pair = Pair::new(1, 2); | |
for i in &pair { let _ = i; } | |
let pair = Pair::new(1, 2); | |
for i in pair.iter() { let _ = i; } | |
let mut pair = Pair::new(1, 2); | |
for i in &mut pair { let _ = i; } | |
let mut pair = Pair::new(1, 2); | |
for i in pair.iter_mut() { let _ = i; } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment