[go: up one dir, main page]

Struct generator::Gn

source ·
pub struct Gn<A = ()> { /* private fields */ }
Expand description

Generator helper

Implementations§

source§

impl<A> Gn<A>

source

pub fn new_scoped<'a, T, F>(f: F) -> Generator<'a, A, T>where F: FnOnce(Scope<'_, A, T>) -> T + Send + 'a, T: Send + 'a, A: Send + 'a,

create a scoped generator with default stack size

Examples found in repository?
examples/pipe.rs (lines 6-11)
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    fn square<'a, T: Iterator<Item = u32> + Send + 'a>(input: T) -> Generator<'a, (), u32> {
        Gn::new_scoped(|mut s| {
            for i in input {
                s.yield_with(i * i);
            }
            done!();
        })
    }

    // fn sum<'a, T: Iterator<Item = u32> + 'a>(input: T) -> impl Iterator<Item = u32> + 'a {
    fn sum<'a, T: Iterator<Item = u32> + Send + 'a>(input: T) -> Generator<'a, (), u32> {
        Gn::new_scoped(|mut s| {
            let mut acc = 0;
            for i in input {
                acc += i;
                s.yield_with(acc);
            }
            done!();
        })
    }
More examples
Hide additional examples
examples/range.rs (lines 5-12)
3
4
5
6
7
8
9
10
11
12
13
14
15
16
fn main() {
    let n = 100000;
    let range = Gn::new_scoped(move |mut s| {
        let mut num = 0;
        while num < n {
            s.yield_(num);
            num += 1;
        }
        done!();
    });

    let sum: usize = range.sum();
    println!("sum ={sum}");
}
examples/fib.rs (lines 4-12)
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
fn main() {
    let g = Gn::new_scoped(|mut s| {
        let (mut a, mut b) = (0, 1);
        while b < 200 {
            std::mem::swap(&mut a, &mut b);
            b += a;
            s.yield_(b);
        }
        done!();
    });

    for i in g {
        println!("{i}");
    }
}
examples/number.rs (lines 4-17)
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
fn factors(n: u32) -> Generator<'static, (), u32> {
    Gn::new_scoped(move |mut s| {
        if n == 0 {
            return 0;
        }

        s.yield_with(1);

        for i in 2..n {
            if n % i == 0 {
                s.yield_with(i);
            }
        }
        done!();
    })
}
examples/yield_from.rs (lines 16-20)
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
fn main() {
    let g1 = Gn::new(|| xrange(0, 10));
    let g2 = Gn::new(|| xrange(10, 20));

    let g = Gn::new_scoped(|mut s| {
        s.yield_from(g1);
        s.yield_from(g2);
        done!();
    });

    g.fold(0, |sum, x| {
        println!("i={}, sum={}", x, sum + x);
        sum + x
    });
}
examples/cd.rs (lines 19-48)
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
fn main() {
    let mut cd_player = Gn::new_scoped(|mut s| {
        let mut state = Stopped;
        loop {
            // println!("{:?}", *state);
            // in release mod without this there is bugs!!!!! (rustc 1.59.0 (9d1b2106e 2022-02-23))
            std::sync::atomic::compiler_fence(std::sync::atomic::Ordering::AcqRel);

            match state {
                Stopped => match s.get_yield() {
                    Some(Play(t)) => {
                        println!("I'm playing {t}");
                        state = Playing;
                    }
                    Some(Stop) => println!("I'm already stopped"),
                    _ => unreachable!("some thing wrong"),
                },

                Playing => match s.get_yield() {
                    Some(Stop) => {
                        println!("I'm stopped");
                        state = Stopped;
                    }
                    Some(Play(_)) => println!("should first stop"),
                    _ => unreachable!("some thing wrong"),
                },
            }

            s.yield_with(state);
        }
    });

    for _ in 0..1000 {
        let ret = cd_player.send(Play("hello world"));
        assert_eq!(ret, Playing);
        let ret = cd_player.send(Play("hello another day"));
        assert_eq!(ret, Playing);
        let ret = cd_player.send(Stop);
        assert_eq!(ret, Stopped);
        let ret = cd_player.send(Stop);
        assert_eq!(ret, Stopped);
        let ret = cd_player.send(Play("hello another day"));
        assert_eq!(ret, Playing);
        let ret = cd_player.send(Stop);
        assert_eq!(ret, Stopped);
    }
}
source

pub fn new_scoped_local<'a, T, F>(f: F) -> LocalGenerator<'a, A, T>where F: FnOnce(Scope<'_, A, T>) -> T + 'a, T: 'a, A: 'a,

create a scoped local generator with default stack size

source

pub fn new_scoped_opt<'a, T, F>(size: usize, f: F) -> Generator<'a, A, T>where F: FnOnce(Scope<'_, A, T>) -> T + Send + 'a, T: Send + 'a, A: Send + 'a,

create a scoped generator with specified stack size

source

pub fn new_scoped_opt_local<'a, T, F>( size: usize, f: F ) -> LocalGenerator<'a, A, T>where F: FnOnce(Scope<'_, A, T>) -> T + 'a, T: 'a, A: 'a,

create a scoped local generator with specified stack size

source§

impl<A: Any> Gn<A>

source

pub fn new<'a, T: Any, F>(f: F) -> Generator<'a, A, T>where F: FnOnce() -> T + Send + 'a,

👎Deprecated since 0.6.18: please use scope version instead

create a new generator with default stack size

Examples found in repository?
examples/get_yield.rs (line 18)
16
17
18
19
20
21
22
23
24
fn main() {
    // we specify the send type is u32
    let mut s = Gn::<u32>::new(|| sum(1));
    let mut i = 1u32;
    while !s.is_done() {
        i = s.send(i);
        println!("{i}");
    }
}
More examples
Hide additional examples
examples/yield_from.rs (line 13)
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
fn main() {
    let g1 = Gn::new(|| xrange(0, 10));
    let g2 = Gn::new(|| xrange(10, 20));

    let g = Gn::new_scoped(|mut s| {
        s.yield_from(g1);
        s.yield_from(g2);
        done!();
    });

    g.fold(0, |sum, x| {
        println!("i={}, sum={}", x, sum + x);
        sum + x
    });
}
examples/send.rs (line 20)
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
fn main() {
    // we specify the send type is u32
    let mut s = Gn::<u32>::new(|| sum(0));
    // first start the generator
    assert_eq!(s.raw_send(None).unwrap(), 0);
    let mut cur = 1;
    let mut last = 1;

    while !s.is_done() {
        // println!("send={}", last);
        mem::swap(&mut cur, &mut last);
        cur = s.send(cur); // s += cur
                           // println!("cur={} last={}", cur, last);
        println!("{cur}");
    }
}
source

pub fn new_opt<'a, T: Any, F>(size: usize, f: F) -> Generator<'a, A, T>where F: FnOnce() -> T + Send + 'a,

create a new generator with specified stack size

Auto Trait Implementations§

§

impl<A> RefUnwindSafe for Gn<A>where A: RefUnwindSafe,

§

impl<A> Send for Gn<A>where A: Send,

§

impl<A> Sync for Gn<A>where A: Sync,

§

impl<A> Unpin for Gn<A>where A: Unpin,

§

impl<A> UnwindSafe for Gn<A>where A: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.