Last active
December 28, 2015 20:09
-
-
Save DaGenix/7555128 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Here is my goal: I'd like to have a struct that basically operates as a state | |
machine. I'd like the current state to be represented as an enum which contains | |
a non-copyable value inside it related to the current state. When proessing each | |
state, I'd like to deconstruct the state, pull out the value inside it, and then | |
put a new value into a new state and transition to that state. In the code | |
I'm actually working on, I'm not allocating on the heap on state transitions, | |
but I think this is more readable for this question. Anyway, is there a better | |
way to do that than by using this next_state() function that I've cooked up? | |
My first attempt was to directly match on the state value, but, I got errors | |
about trying to move out of a & when I did that. | |
*/ | |
// Mutate a state value in place - takes a closure that takes ownership of | |
// the current state value and then returns a new state value along with a | |
// return value. | |
fn next_state<S, R>(state: &mut S, func: |S| -> (S, R)) -> R { | |
use std::cast; | |
use std::unstable::intrinsics; | |
use std::util; | |
unsafe { | |
let current_state = util::replace(state, intrinsics::uninit()); | |
let (next_state, ret) = func(current_state); | |
cast::forget(util::replace(state, next_state)); | |
ret | |
} | |
} | |
enum State { | |
Even(~int), | |
Odd(~int) | |
} | |
struct MyNumber { | |
num: State | |
} | |
impl MyNumber { | |
fn new() -> MyNumber { | |
MyNumber { | |
num: Even(~0) | |
} | |
} | |
fn next(&mut self) -> bool { | |
return do next_state(&mut self.num) |current_state| { | |
match current_state { | |
Even(x) => (Odd(~(*x + 1)), true), | |
Odd(y) => (Even(~(*y + 1)), false) | |
} | |
} | |
} | |
} | |
fn main() { | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment