option::swap_unwrap, the ubiquitous 'option dance'.
This commit is contained in:
parent
7d4742e101
commit
9facb15c49
@ -23,7 +23,7 @@ pure fn get<T: copy>(opt: option<T>) -> T {
|
||||
* Fails if the value equals `none`
|
||||
*/
|
||||
|
||||
alt opt { some(x) { return x; } none { fail ~"option none"; } }
|
||||
alt opt { some(x) { return x; } none { fail ~"option::get none"; } }
|
||||
}
|
||||
|
||||
pure fn expect<T: copy>(opt: option<T>, reason: ~str) -> T {
|
||||
@ -112,7 +112,7 @@ pure fn unwrap<T>(-opt: option<T>) -> T {
|
||||
unsafe {
|
||||
let addr = alt opt {
|
||||
some(x) { ptr::addr_of(x) }
|
||||
none { fail ~"option none" }
|
||||
none { fail ~"option::unwrap none" }
|
||||
};
|
||||
let liberated_value = unsafe::reinterpret_cast(*addr);
|
||||
unsafe::forget(opt);
|
||||
@ -120,6 +120,13 @@ pure fn unwrap<T>(-opt: option<T>) -> T {
|
||||
}
|
||||
}
|
||||
|
||||
/// The ubiquitous option dance.
|
||||
#[inline(always)]
|
||||
fn swap_unwrap<T>(opt: &mut option<T>) -> T {
|
||||
if opt.is_none() { fail ~"option::swap_unwrap none" }
|
||||
unwrap(util::replace(opt, none))
|
||||
}
|
||||
|
||||
pure fn unwrap_expect<T>(-opt: option<T>, reason: ~str) -> T {
|
||||
//! As unwrap, but with a specified failure message.
|
||||
if opt.is_none() { fail reason; }
|
||||
@ -204,6 +211,24 @@ fn test_unwrap_resource() {
|
||||
assert *i == 1;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_option_dance() {
|
||||
let x = some(());
|
||||
let mut y = some(5);
|
||||
let mut y2 = 0;
|
||||
do x.iter |_x| {
|
||||
y2 = swap_unwrap(&mut y);
|
||||
}
|
||||
assert y2 == 5;
|
||||
assert y.is_none();
|
||||
}
|
||||
#[test] #[should_fail] #[ignore(cfg(windows))]
|
||||
fn test_option_too_much_dance() {
|
||||
let mut y = some(util::noncopyable());
|
||||
let _y2 = swap_unwrap(&mut y);
|
||||
let _y3 = swap_unwrap(&mut y);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_option_while_some() {
|
||||
let mut i = 0;
|
||||
|
@ -9,6 +9,7 @@ pure fn id<T>(+x: T) -> T { x }
|
||||
* Swap the values at two mutable locations of the same type, without
|
||||
* deinitialising or copying either one.
|
||||
*/
|
||||
#[inline(always)]
|
||||
fn swap<T>(x: &mut T, y: &mut T) {
|
||||
*x <-> *y;
|
||||
}
|
||||
@ -17,6 +18,7 @@ fn swap<T>(x: &mut T, y: &mut T) {
|
||||
* Replace the value at a mutable location with a new one, returning the old
|
||||
* value, without deinitialising or copying either one.
|
||||
*/
|
||||
#[inline(always)]
|
||||
fn replace<T>(dest: &mut T, +src: T) -> T {
|
||||
let mut tmp = src;
|
||||
swap(dest, &mut tmp);
|
||||
|
Loading…
Reference in New Issue
Block a user