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
#![no_std]
/// # Ad-hoc Iterator
///
/// This is a very small crate providing a macro and a function that allow for
/// conveniently creating iterators on the fly.
///
/// The `Iterator` Trait is very useful. The problem ist just that we can't
/// simply construct an iterator in-place, but rather have to define a struct,
/// `impl` the `Iterator` trait for it, and then return a value of that struct.
///
/// With the [`iterate`](iterate) macro of this crate, you can however do
/// exactly that. See it's documentation for more information.
///
/// With the [`iterator_from`](iterator_from) function, you can directly create
/// an iterator from an `FnMut` closure (which is exactly the same as what the
/// `iterate` macro is doing).
/// Internal, not intended for direct use.
///
/// See [`iterate`](iterate).
#[doc(hidden)]
pub struct __ClosureIterator<F>(pub Option<F>);
impl<T, F: FnMut() -> Option<T>> Iterator for __ClosureIterator<F> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
let r = self.0.as_mut().and_then(|f| f());
if r.is_none() {
self.0 = None;
None
} else {
r
}
}
}
/// Internal, not intended for direct use.
///
/// See [`iterate`](iterate).
#[doc(hidden)]
#[macro_export]
macro_rules! __iterate {
($b:block) => {
::ad_hoc_iterator::iterator_from(move || $b)
};
}
/// Create an ad-hoc iterator.
///
/// # Usage
///
/// The macro is used just like defining a closure. The return type of it's body
/// has to be `Option<T>` for some type T. So at the minimum: `iterate!{ None }`
///
/// The expression `iterate! {...}` is of type `impl Iterator<T>`.
///
/// Any captured variables are moved (like with `move || {...}` closures).
///
/// You can use `return` statements in the body of `iterate!`.
///
/// # Example
///
/// ```
/// use ad_hoc_iterator::iterate;
///
/// fn count_to(n: usize) -> impl Iterator<Item = usize> {
/// let mut i = 0;
/// iterate! {
/// if i < n {
/// i += 1;
/// Some(i-1)
/// } else {
/// None
/// }
/// }
/// }
/// ```
#[macro_export]
macro_rules! iterate {
($( $ts:tt )*) => {
::ad_hoc_iterator::__iterate!{{ $($ts)* }}
};
}
/// Turn a closure into an iterator.
///
/// Each `next()` on the iterator will simply
/// call the closure once. The iterator ends when the closure returns `None`.
///
/// # Example
///
/// ```
/// use ad_hoc_iterator::iterator_from;
///
/// fn count_from_to(n: usize, m: usize) -> impl Iterator<Item = usize> {
/// let mut i = n;
/// iterator_from(move || {
/// if i < m {
/// i += 1;
/// Some(i - 1)
/// } else {
/// None
/// }
/// })
/// }
/// ```
#[inline(always)]
pub fn iterator_from<T, F: FnMut() -> Option<T>>(f: F) -> impl Iterator<Item = T> {
__ClosureIterator(Some(f))
}