/*!

Dynamic vector

A growable vector that makes use of unique pointers so that the
result can be sent between tasks and so forth.

Note that recursive use is not permitted.

*/

// NB: transitionary, de-mode-ing.
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];

use cast::reinterpret_cast;
use ptr::null;

/**
 * A growable, modifiable vector type that accumulates elements into a
 * unique vector.
 *
 * # Limitations on recursive use
 *
 * This class works by swapping the unique vector out of the data
 * structure whenever it is to be used.  Therefore, recursive use is not
 * permitted.  That is, while iterating through a vector, you cannot
 * access the vector in any other way or else the program will fail.  If
 * you wish, you can use the `swap()` method to gain access to the raw
 * vector and transform it or use it any way you like.  Eventually, we
 * may permit read-only access during iteration or other use.
 *
 * # WARNING
 *
 * For maximum performance, this type is implemented using some rather
 * unsafe code.  In particular, this innocent looking `~[mut A]` pointer
 * *may be null!*  Therefore, it is important you not reach into the
 * data structure manually but instead use the provided extensions.
 *
 * The reason that I did not use an unsafe pointer in the structure
 * itself is that I wanted to ensure that the vector would be freed when
 * the dvec is dropped.  The reason that I did not use an `Option<T>`
 * instead of a nullable pointer is that I found experimentally that it
 * becomes approximately 50% slower. This can probably be improved
 * through optimization.  You can run your own experiments using
 * `src/test/bench/vec-append.rs`. My own tests found that using null
 * pointers achieved about 103 million pushes/second.  Using an option
 * type could only produce 47 million pushes/second.
 */
type DVec_<A> = {
    mut data: ~[A]
};

pub enum DVec<A> {
    DVec_(DVec_<A>)
}

/// Creates a new, empty dvec
pub fn DVec<A>() -> DVec<A> {
    DVec_({mut data: ~[]})
}

/// Creates a new dvec with a single element
pub fn from_elem<A>(e: A) -> DVec<A> {
    DVec_({mut data: ~[move e]})
}

/// Creates a new dvec with the contents of a vector
pub fn from_vec<A>(v: ~[A]) -> DVec<A> {
    DVec_({mut data: move v})
}

/// Consumes the vector and returns its contents
pub fn unwrap<A>(d: DVec<A>) -> ~[A] {
    let DVec_({data: v}) <- d;
    move v
}

priv impl<A> DVec<A> {
    pure fn check_not_borrowed() {
        unsafe {
            let data: *() = cast::reinterpret_cast(&self.data);
            if data.is_null() {
                fail ~"Recursive use of dvec";
            }
        }
    }

    #[inline(always)]
    fn check_out<B>(f: &fn(v: ~[A]) -> B) -> B {
        unsafe {
            let mut data = cast::reinterpret_cast(&null::<()>());
            data <-> self.data;
            let data_ptr: *() = cast::reinterpret_cast(&data);
            if data_ptr.is_null() { fail ~"Recursive use of dvec"; }
            return f(move data);
        }
    }

    #[inline(always)]
    fn give_back(data: ~[A]) {
        unsafe {
            self.data = move data;
        }
    }
}

// In theory, most everything should work with any A, but in practice
// almost nothing works without the copy bound due to limitations
// around closures.
impl<A> DVec<A> {
    /// Reserves space for N elements
    fn reserve(count: uint) {
        vec::reserve(&mut self.data, count)
    }

    /**
     * Swaps out the current vector and hands it off to a user-provided
     * function `f`.  The function should transform it however is desired
     * and return a new vector to replace it with.
     */
    #[inline(always)]
    fn swap(f: &fn(v: ~[A]) -> ~[A]) {
        self.check_out(|v| self.give_back(f(move v)))
    }

    /**
     * Swaps out the current vector and hands it off to a user-provided
     * function `f`.  The function should transform it however is desired
     * and return a new vector to replace it with.
     */
    #[inline(always)]
    fn swap_mut(f: &fn(v: ~[mut A]) -> ~[mut A]) {
        do self.swap |v| {
            vec::from_mut(f(vec::to_mut(move v)))
        }
    }

    /// Returns the number of elements currently in the dvec
    pure fn len() -> uint {
        unsafe {
            do self.check_out |v| {
                let l = v.len();
                self.give_back(move v);
                l
            }
        }
    }

    /// Overwrite the current contents
    fn set(w: ~[A]) {
        self.check_not_borrowed();
        self.data <- w;
    }

    /// Remove and return the last element
    fn pop() -> A {
        do self.check_out |v| {
            let mut v <- v;
            let result = v.pop();
            self.give_back(move v);
            move result
        }
    }

    /// Insert a single item at the front of the list
    fn unshift(t: A) {
        unsafe {
            let mut data = cast::reinterpret_cast(&null::<()>());
            data <-> self.data;
            let data_ptr: *() = cast::reinterpret_cast(&data);
            if data_ptr.is_null() { fail ~"Recursive use of dvec"; }
            log(error, ~"a");
            self.data <- ~[move t];
            self.data.push_all_move(move data);
            log(error, ~"b");
        }
    }

    /// Append a single item to the end of the list
    fn push(t: A) {
        self.check_not_borrowed();
        self.data.push(move t);
    }

    /// Remove and return the first element
    fn shift() -> A {
        do self.check_out |v| {
            let mut v = move v;
            let result = v.shift();
            self.give_back(move v);
            move result
        }
    }

    /// Reverse the elements in the list, in place
    fn reverse() {
        do self.check_out |v| {
            let mut v = move v;
            vec::reverse(v);
            self.give_back(move v);
        }
    }

    /// Gives access to the vector as a slice with immutable contents
    fn borrow<R>(op: fn(x: &[A]) -> R) -> R {
        do self.check_out |v| {
            let result = op(v);
            self.give_back(move v);
            move result
        }
    }

    /// Gives access to the vector as a slice with mutable contents
    fn borrow_mut<R>(op: fn(x: &[mut A]) -> R) -> R {
        do self.check_out |v| {
            let mut v = move v;
            let result = op(v);
            self.give_back(move v);
            move result
        }
    }
}

impl<A: Copy> DVec<A> {
    /**
     * Append all elements of a vector to the end of the list
     *
     * Equivalent to `append_iter()` but potentially more efficient.
     */
    fn push_all(ts: &[const A]) {
        self.push_slice(ts, 0u, vec::len(ts));
    }

    /// Appends elements from `from_idx` to `to_idx` (exclusive)
    fn push_slice(ts: &[const A], from_idx: uint, to_idx: uint) {
        do self.swap |v| {
            let mut v <- v;
            let new_len = vec::len(v) + to_idx - from_idx;
            vec::reserve(&mut v, new_len);
            let mut i = from_idx;
            while i < to_idx {
                v.push(ts[i]);
                i += 1u;
            }
            move v
        }
    }

    /**
     * Append all elements of an iterable.
     *
     * Failure will occur if the iterable's `each()` method
     * attempts to access this vector.
     */
    /*
    fn append_iter<A, I:iter::base_iter<A>>(ts: I) {
        do self.swap |v| {
           let mut v = match ts.size_hint() {
             none { v }
             Some(h) {
               let len = v.len() + h;
               let mut v <- v;
               vec::reserve(v, len);
               v
            }
           };

        for ts.each |t| { v.push(*t) };
           v
        }
    }
    */

    /**
     * Gets a copy of the current contents.
     *
     * See `unwrap()` if you do not wish to copy the contents.
     */
    pure fn get() -> ~[A] {
        unsafe {
            do self.check_out |v| {
                let w = copy v;
                self.give_back(move v);
                move w
            }
        }
    }

    /// Copy out an individual element
    #[inline(always)]
    pure fn get_elt(idx: uint) -> A {
        self.check_not_borrowed();
        return self.data[idx];
    }

    /// Overwrites the contents of the element at `idx` with `a`
    fn set_elt(idx: uint, a: A) {
        self.check_not_borrowed();
        self.data[idx] = a;
    }

    /**
     * Overwrites the contents of the element at `idx` with `a`,
     * growing the vector if necessary.  New elements will be initialized
     * with `initval`
     */
    fn grow_set_elt(idx: uint, initval: &A, val: A) {
        do self.swap |v| {
            let mut v = move v;
            v.grow_set(idx, initval, val);
            move v
        }
    }

    /// Returns the last element, failing if the vector is empty
    #[inline(always)]
    pure fn last() -> A {
        self.check_not_borrowed();

        let length = self.len();
        if length == 0 {
            fail ~"attempt to retrieve the last element of an empty vector";
        }

        return self.data[length - 1];
    }

    /// Iterates over the elements in reverse order
    #[inline(always)]
    fn rev_each(f: fn(v: &A) -> bool) {
        do self.swap |v| {
            // FIXME(#2263)---we should be able to write
            // `vec::rev_each(v, f);` but we cannot write now
            for vec::rev_each(v) |e| {
                if !f(e) { break; }
            }
            move v
        }
    }

    /// Iterates over the elements and indices in reverse order
    #[inline(always)]
    fn rev_eachi(f: fn(uint, v: &A) -> bool) {
        do self.swap |v| {
            // FIXME(#2263)---we should be able to write
            // `vec::rev_eachi(v, f);` but we cannot write now
            for vec::rev_eachi(v) |i, e| {
                if !f(i, e) { break; }
            }
            move v
        }
    }
}

impl<A:Copy> DVec<A>: Index<uint,A> {
    pure fn index(idx: uint) -> A {
        self.get_elt(idx)
    }
}

