From 882bb97027b215352c25b05867301bbc78b3441d Mon Sep 17 00:00:00 2001 From: Banyc <36535895+Banyc@users.noreply.github.com> Date: Mon, 11 Dec 2023 15:55:38 +0800 Subject: [PATCH] Write `View::into_iter()` and `Index::iter()` --- src/index.rs | 26 +++++++++++++++++++++++++- src/view.rs | 24 ++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/index.rs b/src/index.rs index 1daeba7..a83725c 100644 --- a/src/index.rs +++ b/src/index.rs @@ -1,4 +1,4 @@ -use std::fmt::{Debug}; +use std::{fmt::{Debug}, marker::PhantomData}; use super::{div_mod, Coated, Isomorphic}; @@ -66,10 +66,34 @@ pub trait Index: Debug + Copy + PartialEq { for i in 0..Self::length(size) { f(Self::from_usize(size, i).1); } } + fn iter(size: Self::Size) -> Iter { + let range_iter = 0..Self::length(size); + Iter:: { range_iter, size, index: PhantomData, } + } + /// Returns a View of the specified size that maps every `Self` to itself. fn all(size: impl Isomorphic) -> All { All(size.to_iso()) } } +pub struct Iter { + range_iter: std::ops::Range, + size: S, + index: PhantomData, +} +impl Iterator for Iter +where + S: Size, + I: Index, +{ + type Item = I; + fn next(&mut self) -> Option { + let Some(i) = self.range_iter.next() else { + return None; + }; + Some(I::from_usize(self.size, i).1) + } +} + // `impl Index for ()` is provided by implementing `StaticIndex`. impl Index for (I,) { diff --git a/src/view.rs b/src/view.rs index 0fba000..837d77d 100644 --- a/src/view.rs +++ b/src/view.rs @@ -251,6 +251,11 @@ pub trait View: Sized { Self::I::each(self.size(), |i| f(self.at(i))); } + fn into_iter(self) -> IntoIter<<::I as Index>::Size, ::I, Self> { + let index_iter = Self::I::iter(self.size()); + IntoIter { index_iter, view: self } + } + /// Creates a `View` with the same `Index` type as `self` such that `at(i)` /// returns `(i, self.at(i))`. /// @@ -661,6 +666,25 @@ impl> View for T { fn at(&self, index: Self::I) -> Self::T { V::at(self, index) } } +pub struct IntoIter { + index_iter: crate::index::Iter, + view: V, +} +impl Iterator for IntoIter +where + S: crate::Size, + I: Index, + V: View, +{ + type Item = V::T; + fn next(&mut self) -> Option { + let Some(i) = self.index_iter.next() else { + return None; + }; + Some(self.view.at(i)) + } +} + // ---------------------------------------------------------------------------- /// A [`View`] that is backed by memory.