about summary refs log tree commit diff
path: root/src/libcore/util.rs
blob: 8487e4ff930e09a97d04aa4f3dda35b81fd2ef03 (plain)
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
// NB: transitionary, de-mode-ing.
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];

/**
 * Miscellaneous helpers for common patterns.
 */

/// The identity function.
pure fn id<T>(+x: T) -> T { x }

/// Ignores a value.
pure fn ignore<T>(+_x: T) { }

/// Sets `*ptr` to `new_value`, invokes `op()`, and then restores the
/// original value of `*ptr`.
#[inline(always)]
fn with<T: copy, R>(
    ptr: &mut T,
    +new_value: T,
    op: &fn() -> R) -> R
{
    // NDM: if swap operator were defined somewhat differently,
    // we wouldn't need to copy...

    let old_value = *ptr;
    *ptr = move new_value;
    let result = op();
    *ptr = move old_value;
    return move result;
}

/**
 * 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;
}

/**
 * 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);
    tmp
}

/// A non-copyable dummy type.
struct NonCopyable {
    i: ();
    new() { self.i = (); }
    drop { }
}

mod tests {
    #[test]
    fn identity_crisis() {
        // Writing a test for the identity function. How did it come to this?
        let x = ~[{mut a: 5, b: false}];
        assert x == id(copy x);
    }
    #[test]
    fn test_swap() {
        let mut x = 31337;
        let mut y = 42;
        swap(&mut x, &mut y);
        assert x == 42;
        assert y == 31337;
    }
    #[test]
    fn test_replace() {
        let mut x = some(NonCopyable());
        let y = replace(&mut x, none);
        assert x.is_none();
        assert y.is_some();
    }
}