/* Module: deque A deque. Untested as of yet. Likely buggy. */ /* Object: t */ type t = obj { // Method: size fn size() -> uint; // Method: add_front fn add_front(T); // Method: add_back fn add_back(T); // Method: pop_front fn pop_front() -> T; // Method: pop_back fn pop_back() -> T; // Method: peek_front fn peek_front() -> T; // Method: peek_back fn peek_back() -> T; // Method: get fn get(int) -> T; }; /* Section: Functions */ /* Function: create */ fn create() -> t { type cell = option::t; let initial_capacity: uint = 32u; // 2^5 /** * Grow is only called on full elts, so nelts is also len(elts), unlike * elsewhere. */ fn grow(nelts: uint, lo: uint, elts: [mutable cell]) -> [mutable cell] { assert (nelts == vec::len(elts)); let rv = [mutable]; let i = 0u; let nalloc = uint::next_power_of_two(nelts + 1u); while i < nalloc { if i < nelts { rv += [mutable elts[(lo + i) % nelts]]; } else { rv += [mutable option::none]; } i += 1u; } ret rv; } fn get(elts: [mutable cell], i: uint) -> T { ret alt elts[i] { option::some(t) { t } _ { fail } }; } obj deque(mutable nelts: uint, mutable lo: uint, mutable hi: uint, mutable elts: [mutable cell]) { fn size() -> uint { ret nelts; } fn add_front(t: T) { let oldlo: uint = lo; if lo == 0u { lo = vec::len::>(elts) - 1u; } else { lo -= 1u; } if lo == hi { elts = grow::(nelts, oldlo, elts); lo = vec::len::>(elts) - 1u; hi = nelts; } elts[lo] = option::some::(t); nelts += 1u; } fn add_back(t: T) { if lo == hi && nelts != 0u { elts = grow::(nelts, lo, elts); lo = 0u; hi = nelts; } elts[hi] = option::some::(t); hi = (hi + 1u) % vec::len::>(elts); 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::(elts, lo); elts[lo] = option::none::; lo = (lo + 1u) % vec::len::>(elts); nelts -= 1u; ret t; } fn pop_back() -> T { if hi == 0u { hi = vec::len::>(elts) - 1u; } else { hi -= 1u; } let t: T = get::(elts, hi); elts[hi] = option::none::; nelts -= 1u; ret t; } fn peek_front() -> T { ret get::(elts, lo); } fn peek_back() -> T { ret get::(elts, hi - 1u); } fn get(i: int) -> T { let idx: uint = (lo + (i as uint)) % vec::len::>(elts); ret get::(elts, idx); } } let v: [mutable cell] = vec::init_elt_mut(option::none, initial_capacity); ret deque::(0u, 0u, 0u, v); } // Local Variables: // mode: rust; // fill-column: 78; // indent-tabs-mode: nil // c-basic-offset: 4 // buffer-file-coding-system: utf-8-unix // End: