Skip to main content

pure_iter/
lib.rs

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