deque.rs 4.0 KB
Newer Older
1 2 3 4 5
/**
 * A deque, for fun.  Untested as of yet.  Likely buggy.
 */

type t[T] = obj {
6
            fn size() -> uint;
7

8 9
            fn add_front(&T t);
            fn add_back(&T t);
10

11 12
            fn pop_front() -> T;
            fn pop_back() -> T;
13

14 15
            fn peek_front() -> T;
            fn peek_back() -> T;
16

17
            fn get(int i) -> T;
18 19 20 21
};

fn create[T]() -> t[T] {

22
    type cell[T] = option::t[T];
23

24
    let uint initial_capacity = 32u; // 2^5
25 26

    /**
27 28
     * Grow is only called on full elts, so nelts is also len(elts), unlike
     * elsewhere.
29
     */
30 31 32
    fn grow[T](uint nelts, uint lo, vec[mutable cell[T]] elts)
        -> vec[mutable cell[T]] {
        assert (nelts == vec::len(elts));
33

34 35
        // FIXME: Making the vector argument an alias is a workaround for
        // issue #375
36
        fn fill[T](uint i, uint nelts, uint lo,
37
                   &vec[mutable cell[T]] old) -> cell[T] {
38 39
            ret if (i < nelts) {
                old.((lo + i) % nelts)
40
            } else {
41
                option::none
42
            };
43 44
        }

45 46
        let uint nalloc = uint::next_power_of_two(nelts + 1u);
        let vec::init_op[cell[T]] copy_op = bind fill[T](_, nelts, lo, elts);
47
        ret vec::init_fn_mut[cell[T]](copy_op, nalloc);
48 49
    }

50
    fn get[T](vec[mutable cell[T]] elts, uint i) -> T {
51
        ret alt (elts.(i)) {
52
            case (option::some(?t)) { t }
53 54
            case (_) { fail }
        };
55
    }
56

57 58 59
    obj deque[T](mutable uint nelts,
                 mutable uint lo,
                 mutable uint hi,
60
                 mutable vec[mutable cell[T]] elts)
61 62 63 64 65 66 67
        {
            fn size() -> uint { ret nelts; }

            fn add_front(&T t) {
                let uint oldlo = lo;

                if (lo == 0u) {
68
                    lo = vec::len[cell[T]](elts) - 1u;
69 70 71 72 73 74
                } else {
                    lo -= 1u;
                }

                if (lo == hi) {
                    elts = grow[T](nelts, oldlo, elts);
75
                    lo = vec::len[cell[T]](elts) - 1u;
76 77 78
                    hi = nelts;
                }

79
                elts.(lo) = option::some[T](t);
80 81 82 83 84 85 86 87 88 89
                nelts += 1u;
            }

            fn add_back(&T t) {
                if (lo == hi && nelts != 0u) {
                    elts = grow[T](nelts, lo, elts);
                    lo = 0u;
                    hi = nelts;
                }

90
                elts.(hi) = option::some[T](t);
91
                hi = (hi + 1u) % vec::len[cell[T]](elts);
92 93 94 95 96 97 98 99 100
                nelts += 1u;
            }

            /**
             * We actually release (turn to none()) the T we're popping so
             * that we don't keep anyone's refcount up unexpectedly.
             */
            fn pop_front() -> T {
                let T t = get[T](elts, lo);
101
                elts.(lo) = option::none[T];
102
                lo = (lo + 1u) % vec::len[cell[T]](elts);
103 104 105 106 107 108
                nelts -= 1u;
                ret t;
            }

            fn pop_back() -> T {
                if (hi == 0u) {
109
                    hi = vec::len[cell[T]](elts) - 1u;
110 111 112 113 114
                } else {
                    hi -= 1u;
                }

                let T t = get[T](elts, hi);
115
                elts.(hi) = option::none[T];
116 117 118 119 120 121 122 123 124 125 126 127 128
                nelts -= 1u;
                ret t;
            }

            fn peek_front() -> T {
                ret get[T](elts, lo);
            }

            fn peek_back() -> T {
                ret get[T](elts, hi - 1u);
            }

            fn get(int i) -> T {
129
                let uint idx = (lo + (i as uint)) % vec::len[cell[T]](elts);
130 131 132 133
                ret get[T](elts, idx);
            }

        }
134 135
    let vec[mutable cell[T]] v = vec::init_elt_mut(option::none,
                                                   initial_capacity);
136 137

    ret deque[T](0u, 0u, 0u, v);
138
}
139 140 141 142 143 144 145 146 147

// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End: