pure_iter/
lib.rs

1#![no_std]
2#![cfg_attr(feature = "unstable", feature(iter_advance_by, try_trait_v2))]
3
4mod adapter_impls {
5    macro_rules! decl {
6        ($($mod:ident :: $adapter:ident);+ $(;)?) => {
7            $(
8                mod $mod;
9                pub use $mod::$adapter;
10            )+
11        };
12    }
13    decl! {
14        map::PureMap;
15    }
16}
17pub use adapter_impls::*;
18
19/// Similar to an [`Iterator`], but assuming the input function has no side effects,
20/// it can avoid additional calls
21pub trait PureIterExt: Iterator + Sized {
22    /// # Examples
23    ///
24    /// ```
25    /// # use std::sync::atomic::{AtomicU32, Ordering::*};
26    /// use pure_iter::PureIterExt;
27    ///
28    /// let mut a = AtomicU32::new(0);
29    /// let mut b = AtomicU32::new(0);
30    ///
31    /// let c = (0..3).map(|_| a.fetch_add(1, Release)).nth(2);
32    /// let d = (0..3).pure_map(|_| b.fetch_add(1, Release)).nth(2);
33    ///
34    /// assert_eq!(c, Some(2));
35    /// assert_eq!(d, Some(0));
36    ///
37    /// assert_eq!(a.load(Acquire), 3);
38    /// assert_eq!(b.load(Acquire), 1);
39    /// ```
40    fn pure_map<F, U>(self, f: F) -> PureMap<Self, F>
41    where F: Fn(Self::Item) -> U,
42    {
43        PureMap::new(self, f)
44    }
45}
46impl<I: Iterator> PureIterExt for I { }