1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
#![cfg_attr(feature = "trusted_len", feature(trusted_len))] #![no_std] //! It is like [repeat](core::iter::repeat), but, you know, finite use core::num::NonZeroUsize; use core::iter::{ Iterator, FusedIterator, ExactSizeIterator, }; /// Creates a new iterator that finitely repeats a single element. /// /// For more details see [RepeatFinite] #[must_use] pub fn repeat_finite<T: Clone>(x: T, n: usize) -> RepeatFinite<T> { RepeatFinite::new(x, n) } /// An iterator that repeats an element a finite amount of times. /// /// It is roughly equivalent to `repeat(x).take(n)` from std. /// It is *slightly* more efficient that [Repeat](core::iter::Repeat) + /// [Take](core::iter::Take) combo, because on last iteration it returns /// the element it holds. /// /// It has the same size as `repeat(x).take(n)` iterator, because instead of /// being effectively a `(T, usize)` pair, it is an `Option<(T, NonZeroUsize)>`. /// This structure also allows to implement it with 100% safe code. /// The only unsafe line of code is the `unsafe impl` for /// [TrustedLen](core::iter::TrustedLen), which is not included by default, /// only with `trusted_len` feature of this crate /// #[derive(Clone, Debug)] pub struct RepeatFinite<T: Clone> { inner: Option<RepeatFiniteInner<T>>, } impl<T: Clone> RepeatFinite<T> { /// Creates an iterator that repeats `x` `n` times.\ /// The same as function [repeat_finite]. /// ``` /// # use repeat_finite::*; /// let s: String = repeat_finite("asdf", 4).collect(); /// assert_eq!(s, "asdf".repeat(4)); /// ``` #[must_use] pub fn new(x: T, n: usize) -> Self { let inner = RepeatFiniteInner::new(x, n); Self { inner } } /// Returns the inner element.\ /// Note, that this is NOT equivalent to `last()`, because /// iteration can cause side-effects. /// ``` /// # use repeat_finite::*; /// let b = Box::new([1u8,2,3]); /// let mut it = repeat_finite(b, 3); /// assert_eq!(it.next(), Some(Box::new([1,2,3]))); /// assert_eq!(it.next(), Some(Box::new([1,2,3]))); /// /// let b2: Box<[u8]> = it.try_into_inner().unwrap(); /// ``` #[must_use] pub fn try_into_inner(self) -> Option<T> { self.inner.map(|inner| inner.value) } /// Tries to change the number of iteration, returns the new number of iterations. /// ``` /// # use repeat_finite::*; /// let b = Box::new([1u8,2,3]); /// let mut it = repeat_finite(b, 3); /// assert_eq!(it.next(), Some(Box::new([1,2,3]))); /// assert_eq!(it.next(), Some(Box::new([1,2,3]))); /// /// it.try_set_count(0); /// assert_eq!(it.try_into_inner(), None); /// ``` pub fn try_set_count(&mut self, count: usize) -> usize { if let Some(n) = NonZeroUsize::new(count) { if let Some(inner) = self.inner.as_mut() { inner.count = n; return count; } /* else (if self.inner == None) */ return 0; } /* else (if n == 0) */ self.inner.take(); return 0; } /// Use this instead of `take()`.\ /// Effectively sets the counter to min(counter, n) and returns modified self. /// ``` /// # use repeat_finite::*; /// let mut it = repeat_finite("asdf", 42).take_n(1); /// assert_eq!(it.next(), Some("asdf")); /// assert_eq!(it.next(), None); /// ``` pub fn take_n(mut self, n: usize) -> Self { if let Some(n) = NonZeroUsize::new(n) { if let Some(inner) = self.inner.as_mut() { inner.count = core::cmp::min(n, inner.count); } return self; } /* else (if n == 0) */ self.inner.take(); return self; } /// Use this instead of `cycle()`. /// It won't cycle forever, but `usize::MAX` times, so close enough to that.\ /// If the iterator is exhausted, it stays the same, otherwise counter /// is set to `usize::MAX`. /// ``` /// # use repeat_finite::*; /// let it = repeat_finite("asdf", 1); /// let mut it = it.cycle_nearly_forever(); /// /// assert_eq!(it.next(), Some("asdf")); /// assert_eq!(it.next(), Some("asdf")); /// assert_eq!(it.next(), Some("asdf")); /// assert_eq!(it.next(), Some("asdf")); /// # assert_eq!(it.try_set_count(2), 2); /// // One eternity later... /// assert_eq!(it.next(), Some("asdf")); /// assert_eq!(it.next(), Some("asdf")); /// assert_eq!(it.next(), None); /// ``` pub fn cycle_nearly_forever(mut self) -> Self { self.try_set_count(usize::MAX); return self; } } impl<T: Clone> Iterator for RepeatFinite<T> { type Item = T; #[inline] fn next(&mut self) -> Option<Self::Item> { let inner = self.inner.as_mut()?; let count = inner.count.get(); if let Some(n) = NonZeroUsize::new(count - 1) { inner.count = n; return Some(inner.value.clone()); } self.inner.take().map(|inner| inner.value) } fn size_hint(&self) -> (usize, Option<usize>) { let n = self.inner.as_ref() .map_or(0, |inner| inner.count.get()); (n, Some(n)) } fn count(self) -> usize { self.inner.map_or(0, |inner| inner.count.get()) } /* (1.46 nightly) Currently `Cycle` and `Take` have private constructors */ /* fn cycle(self) -> Cycle<Self> { self.inner.as_mut() .map(|inner| inner.count = NonZeroUsize::new(usize::MAX).unwrap()); Cycle::new(self) } fn take(self, n: usize) -> Take<Self> { let count = self.len(); if n < count { self.try_set_len(n); return Take::new(self, n); } return Take::new(self, count); } */ } impl<T: Clone> FusedIterator for RepeatFinite<T> {} impl<T: Clone> ExactSizeIterator for RepeatFinite<T> {} #[cfg(feature = "trusted_len")] unsafe impl<T: Clone> core::iter::TrustedLen for RepeatFinite<T> {} impl<T: Clone> Default for RepeatFinite<T> { fn default() -> Self { Self { inner: None } } } /* non-public stuff */ #[derive(Clone, Debug)] struct RepeatFiniteInner<T> { value: T, count: NonZeroUsize, } impl<T> RepeatFiniteInner<T> { fn new(value: T, count: usize) -> Option<Self> { let count = NonZeroUsize::new(count)?; Some(Self { value, count }) } }