// A variable-sized container that can hold both unrestricted types and resources. module Vector { // Vector containing data of type Item. native struct T; native public empty(): Self.T; // Return the length of the vector. native public length(v: &Self.T): u64; // Acquire an immutable reference to the ith element of the vector. native public borrow(v: &Self.T, i: u64): ∈ // Add an element to the end of the vector. native public push_back(v: &mut Self.T, e: Element); // Get mutable reference to the ith element in the vector, abort if out of bound. native public borrow_mut(v: &mut Self.T, idx: u64): &mut Element; // Pop an element from the end of vector, abort if the vector is empty. native public pop_back(v: &mut Self.T): Element; // Destroy the vector, abort if not empty. native public destroy_empty(v: Self.T); // Swaps the elements at the i'th and j'th indices in the vector. native public swap(v: &mut Self.T, i: u64, j: u64); // Reverses the order of the elements in the vector in place. public reverse(v: &mut Self.T) { let front_index: u64; let back_index: u64; let len: u64; len = Self.length(freeze(copy(v))); if (copy(len) == 0) { return; } assert(copy(len) > 0, 0); front_index = 0; back_index = move(len) - 1; while (copy(front_index) < copy(back_index)) { Self.swap(copy(v), copy(front_index), copy(back_index)); front_index = move(front_index) + 1; back_index = move(back_index) - 1; } return; } // Moves all of the elements of the `other` vector into the `lhs` vector. public append(lhs: &mut Self.T, other: Self.T) { Self.reverse(&mut other); while (!Self.is_empty(&other)) { Self.push_back( copy(lhs), Self.pop_back(&mut other) ); } Self.destroy_empty(move(other)); return; } // Return true if the vector has no elements public is_empty(v: &Self.T): bool { return Self.length(move(v)) == 0; } }