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 })
    }
}