use std::borrow::Borrow;
use std::cmp::Ordering;
use std::fmt::{Debug, Error, Formatter};
use std::hash::{Hash, Hasher};
use std::iter::Sum;
use std::iter::{Chain, FromIterator, FusedIterator};
use std::mem::{replace, swap};
use std::ops::{Add, Index, IndexMut, RangeBounds};
use crate::nodes::chunk::{Chunk, Iter as ChunkIter, CHUNK_SIZE};
use crate::nodes::rrb::{
    ConsumingIter as ConsumingNodeIter, Node, PopResult, PushResult, SplitResult,
};
use crate::sort;
use crate::util::{clone_ref, swap_indices, to_range, Ref, Side};
use self::Vector::{Empty, Full, Single};
mod focus;
pub use self::focus::{Focus, FocusMut};
#[macro_export]
macro_rules! vector {
    () => { $crate::vector::Vector::new() };
    ( $($x:expr),* ) => {{
        let mut l = $crate::vector::Vector::new();
        $(
            l.push_back($x);
        )*
            l
    }};
    ( $($x:expr ,)* ) => {{
        let mut l = $crate::vector::Vector::new();
        $(
            l.push_back($x);
        )*
            l
    }};
}
pub enum Vector<A> {
    #[doc(hidden)]
    Empty,
    #[doc(hidden)]
    Single(Ref<Chunk<A>>),
    #[doc(hidden)]
    Full(RRB<A>),
}
#[doc(hidden)]
pub struct RRB<A> {
    length: usize,
    middle_level: usize,
    outer_f: Ref<Chunk<A>>,
    inner_f: Ref<Chunk<A>>,
    middle: Ref<Node<A>>,
    inner_b: Ref<Chunk<A>>,
    outer_b: Ref<Chunk<A>>,
}
impl<A> Clone for RRB<A> {
    fn clone(&self) -> Self {
        RRB {
            length: self.length,
            middle_level: self.middle_level,
            outer_f: self.outer_f.clone(),
            inner_f: self.inner_f.clone(),
            middle: self.middle.clone(),
            inner_b: self.inner_b.clone(),
            outer_b: self.outer_b.clone(),
        }
    }
}
impl<A: Clone> Vector<A> {
    
    
    fn needs_promotion(&self) -> bool {
        match self {
            Empty => true,
            Single(chunk) if chunk.is_full() => true,
            _ => false,
        }
    }
    
    fn promote_empty(&mut self) {
        if let Empty = self {
            *self = Single(Ref::new(Chunk::new()))
        }
    }
    
    
    fn promote_front(&mut self) {
        let chunk = match self {
            Empty => return self.promote_empty(),
            Single(chunk) => chunk.clone(),
            _ => return,
        };
        *self = Full(RRB {
            length: chunk.len(),
            middle_level: 0,
            outer_f: Ref::new(Chunk::new()),
            inner_f: chunk,
            middle: Ref::new(Node::new()),
            inner_b: Ref::new(Chunk::new()),
            outer_b: Ref::new(Chunk::new()),
        })
    }
    
    
    fn promote_back(&mut self) {
        let chunk = match self {
            Empty => return self.promote_empty(),
            Single(chunk) => chunk.clone(),
            _ => return,
        };
        *self = Full(RRB {
            length: chunk.len(),
            middle_level: 0,
            outer_f: Ref::new(Chunk::new()),
            inner_f: Ref::new(Chunk::new()),
            middle: Ref::new(Node::new()),
            inner_b: chunk,
            outer_b: Ref::new(Chunk::new()),
        })
    }
    
    #[must_use]
    pub fn new() -> Self {
        Empty
    }
    
    
    
    
    
    
    
    
    
    
    
    
    #[inline]
    #[must_use]
    pub fn len(&self) -> usize {
        match self {
            Empty => 0,
            Single(chunk) => chunk.len(),
            Full(tree) => tree.length,
        }
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    #[inline]
    #[must_use]
    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }
    
    
    
    #[inline]
    #[must_use]
    pub fn iter(&self) -> Iter<A> {
        Iter::new(self)
    }
    
    
    
    #[inline]
    #[must_use]
    pub fn iter_mut(&mut self) -> IterMut<A> {
        IterMut::new(self)
    }
    
    
    
    
    
    
    
    #[inline]
    #[must_use]
    #[deprecated(
        since = "12.3.0",
        note = "renamed to `leaves` to avoid confusion with Vec::chunks"
    )]
    pub fn chunks(&self) -> Chunks<'_, A> {
        Chunks::new(self)
    }
    
    
    
    
    
    
    
    #[inline]
    #[must_use]
    #[deprecated(
        since = "12.3.0",
        note = "renamed to `leaves_mut` to avoid confusion with Vec::chunks"
    )]
    pub fn chunks_mut(&mut self) -> ChunksMut<'_, A> {
        ChunksMut::new(self)
    }
    
    
    
    
    
    
    
    
    
    #[inline]
    #[must_use]
    pub fn leaves(&self) -> Chunks<'_, A> {
        Chunks::new(self)
    }
    
    
    
    
    
    
    
    
    
    #[inline]
    #[must_use]
    pub fn leaves_mut(&mut self) -> ChunksMut<'_, A> {
        ChunksMut::new(self)
    }
    
    
    
    
    
    #[inline]
    #[must_use]
    pub fn focus(&self) -> Focus<'_, A> {
        Focus::new(self)
    }
    
    
    
    
    
    #[inline]
    #[must_use]
    pub fn focus_mut(&mut self) -> FocusMut<'_, A> {
        FocusMut::new(self)
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    #[must_use]
    pub fn get(&self, index: usize) -> Option<&A> {
        if index >= self.len() {
            return None;
        }
        match self {
            Empty => None,
            Single(chunk) => chunk.get(index),
            Full(tree) => {
                let mut local_index = index;
                if local_index < tree.outer_f.len() {
                    return Some(&tree.outer_f[local_index]);
                }
                local_index -= tree.outer_f.len();
                if local_index < tree.inner_f.len() {
                    return Some(&tree.inner_f[local_index]);
                }
                local_index -= tree.inner_f.len();
                if local_index < tree.middle.len() {
                    return Some(tree.middle.index(tree.middle_level, local_index));
                }
                local_index -= tree.middle.len();
                if local_index < tree.inner_b.len() {
                    return Some(&tree.inner_b[local_index]);
                }
                local_index -= tree.inner_b.len();
                Some(&tree.outer_b[local_index])
            }
        }
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    #[must_use]
    pub fn get_mut(&mut self, index: usize) -> Option<&mut A> {
        if index >= self.len() {
            return None;
        }
        match self {
            Empty => None,
            Single(chunk) => Ref::make_mut(chunk).get_mut(index),
            Full(tree) => {
                let mut local_index = index;
                if local_index < tree.outer_f.len() {
                    let outer_f = Ref::make_mut(&mut tree.outer_f);
                    return Some(&mut outer_f[local_index]);
                }
                local_index -= tree.outer_f.len();
                if local_index < tree.inner_f.len() {
                    let inner_f = Ref::make_mut(&mut tree.inner_f);
                    return Some(&mut inner_f[local_index]);
                }
                local_index -= tree.inner_f.len();
                if local_index < tree.middle.len() {
                    let middle = Ref::make_mut(&mut tree.middle);
                    return Some(middle.index_mut(tree.middle_level, local_index));
                }
                local_index -= tree.middle.len();
                if local_index < tree.inner_b.len() {
                    let inner_b = Ref::make_mut(&mut tree.inner_b);
                    return Some(&mut inner_b[local_index]);
                }
                local_index -= tree.inner_b.len();
                let outer_b = Ref::make_mut(&mut tree.outer_b);
                Some(&mut outer_b[local_index])
            }
        }
    }
    
    
    
    
    
    #[inline]
    #[must_use]
    pub fn front(&self) -> Option<&A> {
        self.get(0)
    }
    
    
    
    
    
    #[inline]
    #[must_use]
    pub fn front_mut(&mut self) -> Option<&mut A> {
        self.get_mut(0)
    }
    
    
    
    
    
    
    
    
    
    #[inline]
    #[must_use]
    pub fn head(&self) -> Option<&A> {
        self.get(0)
    }
    
    
    
    
    
    #[must_use]
    pub fn back(&self) -> Option<&A> {
        if self.is_empty() {
            None
        } else {
            self.get(self.len() - 1)
        }
    }
    
    
    
    
    
    #[must_use]
    pub fn back_mut(&mut self) -> Option<&mut A> {
        if self.is_empty() {
            None
        } else {
            let len = self.len();
            self.get_mut(len - 1)
        }
    }
    
    
    
    
    
    
    
    
    
    #[inline]
    #[must_use]
    pub fn last(&self) -> Option<&A> {
        self.back()
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    #[must_use]
    pub fn index_of(&self, value: &A) -> Option<usize>
    where
        A: PartialEq,
    {
        for (index, item) in self.iter().enumerate() {
            if value == item {
                return Some(index);
            }
        }
        None
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    #[inline]
    #[must_use]
    pub fn contains(&self, value: &A) -> bool
    where
        A: PartialEq,
    {
        self.index_of(value).is_some()
    }
    
    
    
    
    
    
    pub fn clear(&mut self) {
        if !self.is_empty() {
            *self = Single(Ref::new(Chunk::new()));
        }
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    #[must_use]
    pub fn binary_search_by<F>(&self, mut f: F) -> Result<usize, usize>
    where
        F: FnMut(&A) -> Ordering,
    {
        let mut size = self.len();
        if size == 0 {
            return Err(0);
        }
        let mut base = 0;
        while size > 1 {
            let half = size / 2;
            let mid = base + half;
            base = match f(&self[mid]) {
                Ordering::Greater => base,
                _ => mid,
            };
            size -= half;
        }
        match f(&self[base]) {
            Ordering::Equal => Ok(base),
            Ordering::Greater => Err(base),
            Ordering::Less => Err(base + 1),
        }
    }
    
    
    
    
    
    
    
    
    #[must_use]
    pub fn binary_search(&self, value: &A) -> Result<usize, usize>
    where
        A: Ord,
    {
        self.binary_search_by(|e| e.cmp(value))
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    #[must_use]
    pub fn binary_search_by_key<B, F>(&self, b: &B, mut f: F) -> Result<usize, usize>
    where
        F: FnMut(&A) -> B,
        B: Ord,
    {
        self.binary_search_by(|k| f(k).cmp(b))
    }
}
impl<A: Clone> Vector<A> {
    
    
    
    
    
    #[inline]
    #[must_use]
    #[deprecated(since = "12.3.0", note = "renamed to `unit` for consistency")]
    pub fn singleton(a: A) -> Self {
        Self::unit(a)
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    #[inline]
    #[must_use]
    pub fn unit(a: A) -> Self {
        Single(Ref::new(Chunk::unit(a)))
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    #[must_use]
    pub fn update(&self, index: usize, value: A) -> Self {
        let mut out = self.clone();
        out[index] = value;
        out
    }
    
    
    
    
    
    
    
    #[inline]
    pub fn set(&mut self, index: usize, value: A) -> A {
        replace(&mut self[index], value)
    }
    
    
    
    pub fn swap(&mut self, i: usize, j: usize) {
        swap_indices(self, i, j)
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    pub fn push_front(&mut self, value: A) {
        if self.needs_promotion() {
            self.promote_back();
        }
        match self {
            Empty => unreachable!("promote should have promoted the Empty"),
            Single(chunk) => Ref::make_mut(chunk).push_front(value),
            Full(tree) => tree.push_front(value),
        }
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    pub fn push_back(&mut self, value: A) {
        if self.needs_promotion() {
            self.promote_front();
        }
        match self {
            Empty => unreachable!("promote should have promoted the Empty"),
            Single(chunk) => Ref::make_mut(chunk).push_back(value),
            Full(tree) => tree.push_back(value),
        }
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    pub fn pop_front(&mut self) -> Option<A> {
        if self.is_empty() {
            None
        } else {
            match self {
                Empty => None,
                Single(chunk) => Some(Ref::make_mut(chunk).pop_front()),
                Full(tree) => tree.pop_front(),
            }
        }
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    pub fn pop_back(&mut self) -> Option<A> {
        if self.is_empty() {
            None
        } else {
            match self {
                Empty => None,
                Single(chunk) => Some(Ref::make_mut(chunk).pop_back()),
                Full(tree) => tree.pop_back(),
            }
        }
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    pub fn append(&mut self, mut other: Self) {
        if other.is_empty() {
            return;
        }
        if self.is_empty() {
            replace(self, other);
            return;
        }
        let total_length = self
            .len()
            .checked_add(other.len())
            .expect("Vector length overflow");
        match self {
            Empty => unreachable!("empty vecs are handled before this"),
            Single(left) => {
                match other {
                    
                    
                    Single(ref mut right) if total_length <= CHUNK_SIZE => {
                        Ref::make_mut(left).append(Ref::make_mut(right));
                        return;
                    }
                    
                    
                    ref mut right if total_length <= CHUNK_SIZE => {
                        while let Some(value) = right.pop_front() {
                            Ref::make_mut(left).push_back(value);
                        }
                        return;
                    }
                    _ => {}
                }
            }
            Full(left) => {
                if let Full(mut right) = other {
                    
                    
                    
                    if left.middle.is_empty()
                        && right.middle.is_empty()
                        && left.outer_b.is_empty()
                        && left.inner_b.is_empty()
                        && right.outer_f.is_empty()
                        && right.inner_f.is_empty()
                    {
                        left.inner_b = right.inner_b;
                        left.outer_b = right.outer_b;
                        left.length = total_length;
                        return;
                    }
                    
                    
                    if left.middle.is_empty()
                        && right.middle.is_empty()
                        && total_length <= CHUNK_SIZE * 4
                    {
                        while let Some(value) = right.pop_front() {
                            left.push_back(value);
                        }
                        return;
                    }
                    
                    let inner_b1 = left.inner_b.clone();
                    left.push_middle(Side::Right, inner_b1);
                    let outer_b1 = left.outer_b.clone();
                    left.push_middle(Side::Right, outer_b1);
                    let inner_f2 = right.inner_f.clone();
                    right.push_middle(Side::Left, inner_f2);
                    let outer_f2 = right.outer_f.clone();
                    right.push_middle(Side::Left, outer_f2);
                    let mut middle1 = clone_ref(replace(&mut left.middle, Ref::from(Node::new())));
                    let mut middle2 = clone_ref(right.middle);
                    let normalised_middle = if left.middle_level > right.middle_level {
                        middle2 = middle2.elevate(left.middle_level - right.middle_level);
                        left.middle_level
                    } else if left.middle_level < right.middle_level {
                        middle1 = middle1.elevate(right.middle_level - left.middle_level);
                        right.middle_level
                    } else {
                        left.middle_level
                    };
                    left.middle = Ref::new(Node::merge(
                        Ref::from(middle1),
                        Ref::from(middle2),
                        normalised_middle,
                    ));
                    left.middle_level = normalised_middle + 1;
                    left.inner_b = right.inner_b;
                    left.outer_b = right.outer_b;
                    left.length = total_length;
                    left.prune();
                    return;
                }
            }
        }
        
        
        self.promote_front();
        other.promote_back();
        self.append(other)
    }
    
    
    
    
    
    
    pub fn retain<F>(&mut self, mut f: F)
    where
        F: FnMut(&A) -> bool,
    {
        let len = self.len();
        let mut del = 0;
        {
            let mut focus = self.focus_mut();
            for i in 0..len {
                if !f(focus.index(i)) {
                    del += 1;
                } else if del > 0 {
                    focus.swap(i - del, i);
                }
            }
        }
        if del > 0 {
            self.split_off(len - del);
        }
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    pub fn split_at(mut self, index: usize) -> (Self, Self) {
        let right = self.split_off(index);
        (self, right)
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    pub fn split_off(&mut self, index: usize) -> Self {
        assert!(index <= self.len());
        match self {
            Empty => Empty,
            Single(chunk) => Single(Ref::new(Ref::make_mut(chunk).split_off(index))),
            Full(tree) => {
                let mut local_index = index;
                if local_index < tree.outer_f.len() {
                    let of2 = Ref::make_mut(&mut tree.outer_f).split_off(local_index);
                    let right = RRB {
                        length: tree.length - index,
                        middle_level: tree.middle_level,
                        outer_f: Ref::new(of2),
                        inner_f: replace_def(&mut tree.inner_f),
                        middle: replace_def(&mut tree.middle),
                        inner_b: replace_def(&mut tree.inner_b),
                        outer_b: replace_def(&mut tree.outer_b),
                    };
                    tree.length = index;
                    tree.middle_level = 0;
                    return Full(right);
                }
                local_index -= tree.outer_f.len();
                if local_index < tree.inner_f.len() {
                    let if2 = Ref::make_mut(&mut tree.inner_f).split_off(local_index);
                    let right = RRB {
                        length: tree.length - index,
                        middle_level: tree.middle_level,
                        outer_f: Ref::new(if2),
                        inner_f: Ref::<Chunk<A>>::default(),
                        middle: replace_def(&mut tree.middle),
                        inner_b: replace_def(&mut tree.inner_b),
                        outer_b: replace_def(&mut tree.outer_b),
                    };
                    tree.length = index;
                    tree.middle_level = 0;
                    swap(&mut tree.outer_b, &mut tree.inner_f);
                    return Full(right);
                }
                local_index -= tree.inner_f.len();
                if local_index < tree.middle.len() {
                    let mut right_middle = tree.middle.clone();
                    let (c1, c2) = {
                        let m1 = Ref::make_mut(&mut tree.middle);
                        let m2 = Ref::make_mut(&mut right_middle);
                        match m1.split(tree.middle_level, Side::Right, local_index) {
                            SplitResult::Dropped(_) => (),
                            SplitResult::OutOfBounds => unreachable!(),
                        };
                        match m2.split(tree.middle_level, Side::Left, local_index) {
                            SplitResult::Dropped(_) => (),
                            SplitResult::OutOfBounds => unreachable!(),
                        };
                        let c1 = match m1.pop_chunk(tree.middle_level, Side::Right) {
                            PopResult::Empty => Ref::<Chunk<A>>::default(),
                            PopResult::Done(chunk) => chunk,
                            PopResult::Drained(chunk) => {
                                m1.clear_node();
                                chunk
                            }
                        };
                        let c2 = match m2.pop_chunk(tree.middle_level, Side::Left) {
                            PopResult::Empty => Ref::<Chunk<A>>::default(),
                            PopResult::Done(chunk) => chunk,
                            PopResult::Drained(chunk) => {
                                m2.clear_node();
                                chunk
                            }
                        };
                        (c1, c2)
                    };
                    let mut right = RRB {
                        length: tree.length - index,
                        middle_level: tree.middle_level,
                        outer_f: c2,
                        inner_f: Ref::<Chunk<A>>::default(),
                        middle: right_middle,
                        inner_b: replace_def(&mut tree.inner_b),
                        outer_b: replace(&mut tree.outer_b, c1),
                    };
                    tree.length = index;
                    tree.prune();
                    right.prune();
                    return Full(right);
                }
                local_index -= tree.middle.len();
                if local_index < tree.inner_b.len() {
                    let ib2 = Ref::make_mut(&mut tree.inner_b).split_off(local_index);
                    let right = RRB {
                        length: tree.length - index,
                        outer_b: replace_def(&mut tree.outer_b),
                        outer_f: Ref::new(ib2),
                        ..RRB::new()
                    };
                    tree.length = index;
                    swap(&mut tree.outer_b, &mut tree.inner_b);
                    return Full(right);
                }
                local_index -= tree.inner_b.len();
                let ob2 = Ref::make_mut(&mut tree.outer_b).split_off(local_index);
                tree.length = index;
                Single(Ref::new(ob2))
            }
        }
    }
    
    
    
    
    #[must_use]
    pub fn skip(&self, count: usize) -> Self {
        
        self.clone().split_off(count)
    }
    
    
    
    
    #[must_use]
    pub fn take(&self, count: usize) -> Self {
        
        let mut left = self.clone();
        left.split_off(count);
        left
    }
    
    
    
    
    
    
    
    pub fn truncate(&mut self, len: usize) {
        
        self.split_off(len);
    }
    
    
    
    
    
    
    
    pub fn slice<R>(&mut self, range: R) -> Self
    where
        R: RangeBounds<usize>,
    {
        let r = to_range(&range, self.len());
        if r.start >= r.end || r.start >= self.len() {
            return Vector::new();
        }
        let mut middle = self.split_off(r.start);
        let right = middle.split_off(r.end - r.start);
        self.append(right);
        middle
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    pub fn insert(&mut self, index: usize, value: A) {
        if index == 0 {
            return self.push_front(value);
        }
        if index == self.len() {
            return self.push_back(value);
        }
        assert!(index < self.len());
        match self {
            Single(chunk) if chunk.len() < CHUNK_SIZE => Ref::make_mut(chunk).insert(index, value),
            
            _ => {
                let right = self.split_off(index);
                self.push_back(value);
                self.append(right);
            }
        }
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    pub fn remove(&mut self, index: usize) -> A {
        assert!(index < self.len());
        match self {
            Single(chunk) => Ref::make_mut(chunk).remove(index),
            _ => {
                if index == 0 {
                    return self.pop_front().unwrap();
                }
                if index == self.len() - 1 {
                    return self.pop_back().unwrap();
                }
                
                let mut right = self.split_off(index);
                let value = right.pop_front().unwrap();
                self.append(right);
                value
            }
        }
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    pub fn insert_ord(&mut self, item: A)
    where
        A: Ord,
    {
        match self.binary_search(&item) {
            Ok(index) => self.insert(index, item),
            Err(index) => self.insert(index, item),
        }
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    pub fn sort(&mut self)
    where
        A: Ord,
    {
        self.sort_by(Ord::cmp)
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    pub fn sort_by<F>(&mut self, cmp: F)
    where
        F: Fn(&A, &A) -> Ordering,
    {
        let len = self.len();
        if len > 1 {
            sort::quicksort(&mut self.focus_mut(), 0, len - 1, &cmp);
        }
    }
    #[allow(dead_code)]
    pub(crate) fn assert_invariants(&self) {
        if let Vector::Full(ref tree) = self {
            tree.middle.assert_invariants();
        }
    }
}
impl<A: Clone> RRB<A> {
    fn into_iter(
        self,
    ) -> Chain<
        Chain<Chain<Chain<ChunkIter<A>, ChunkIter<A>>, ConsumingNodeIter<A>>, ChunkIter<A>>,
        ChunkIter<A>,
    > {
        let outer_f = clone_ref(self.outer_f).into_iter();
        let inner_f = clone_ref(self.inner_f).into_iter();
        let middle = ConsumingNodeIter::new(clone_ref(self.middle), self.middle_level);
        let inner_b = clone_ref(self.inner_b).into_iter();
        let outer_b = clone_ref(self.outer_b).into_iter();
        outer_f
            .chain(inner_f)
            .chain(middle)
            .chain(inner_b)
            .chain(outer_b)
    }
    fn new() -> Self {
        RRB {
            length: 0,
            middle_level: 0,
            outer_f: Ref::new(Chunk::new()),
            inner_f: Ref::new(Chunk::new()),
            middle: Ref::new(Node::new()),
            inner_b: Ref::new(Chunk::new()),
            outer_b: Ref::new(Chunk::new()),
        }
    }
    fn prune(&mut self) {
        if self.middle.is_empty() {
            self.middle = Ref::new(Node::new());
            self.middle_level = 0;
        } else {
            while self.middle_level > 0 && self.middle.is_single() {
                self.middle = self.middle.first_child().clone();
                self.middle_level -= 1;
            }
        }
    }
    fn pop_front(&mut self) -> Option<A> {
        if self.length == 0 {
            return None;
        }
        if self.outer_f.is_empty() {
            if self.inner_f.is_empty() {
                if self.middle.is_empty() {
                    if self.inner_b.is_empty() {
                        swap(&mut self.outer_f, &mut self.outer_b);
                    } else {
                        swap(&mut self.outer_f, &mut self.inner_b);
                    }
                } else {
                    self.outer_f = self.pop_middle(Side::Left).unwrap();
                }
            } else {
                swap(&mut self.outer_f, &mut self.inner_f);
            }
        }
        self.length -= 1;
        let outer_f = Ref::make_mut(&mut self.outer_f);
        Some(outer_f.pop_front())
    }
    fn pop_back(&mut self) -> Option<A> {
        if self.length == 0 {
            return None;
        }
        if self.outer_b.is_empty() {
            if self.inner_b.is_empty() {
                if self.middle.is_empty() {
                    if self.inner_f.is_empty() {
                        swap(&mut self.outer_b, &mut self.outer_f);
                    } else {
                        swap(&mut self.outer_b, &mut self.inner_f);
                    }
                } else {
                    self.outer_b = self.pop_middle(Side::Right).unwrap();
                }
            } else {
                swap(&mut self.outer_b, &mut self.inner_b);
            }
        }
        self.length -= 1;
        let outer_b = Ref::make_mut(&mut self.outer_b);
        Some(outer_b.pop_back())
    }
    fn push_front(&mut self, value: A) {
        if self.outer_f.is_full() {
            swap(&mut self.outer_f, &mut self.inner_f);
            if !self.outer_f.is_empty() {
                let mut chunk = Ref::new(Chunk::new());
                swap(&mut chunk, &mut self.outer_f);
                self.push_middle(Side::Left, chunk);
            }
        }
        self.length = self.length.checked_add(1).expect("Vector length overflow");
        let outer_f = Ref::make_mut(&mut self.outer_f);
        outer_f.push_front(value)
    }
    fn push_back(&mut self, value: A) {
        if self.outer_b.is_full() {
            swap(&mut self.outer_b, &mut self.inner_b);
            if !self.outer_b.is_empty() {
                let mut chunk = Ref::new(Chunk::new());
                swap(&mut chunk, &mut self.outer_b);
                self.push_middle(Side::Right, chunk);
            }
        }
        self.length = self.length.checked_add(1).expect("Vector length overflow");
        let outer_b = Ref::make_mut(&mut self.outer_b);
        outer_b.push_back(value)
    }
    fn push_middle(&mut self, side: Side, chunk: Ref<Chunk<A>>) {
        if chunk.is_empty() {
            return;
        }
        let new_middle = {
            let middle = Ref::make_mut(&mut self.middle);
            match middle.push_chunk(self.middle_level, side, chunk) {
                PushResult::Done => return,
                PushResult::Full(chunk, _num_drained) => Ref::from({
                    match side {
                        Side::Left => Node::from_chunk(self.middle_level, chunk)
                            .join_branches(middle.clone(), self.middle_level),
                        Side::Right => middle.clone().join_branches(
                            Node::from_chunk(self.middle_level, chunk),
                            self.middle_level,
                        ),
                    }
                }),
            }
        };
        self.middle_level += 1;
        self.middle = new_middle;
    }
    fn pop_middle(&mut self, side: Side) -> Option<Ref<Chunk<A>>> {
        let chunk = {
            let middle = Ref::make_mut(&mut self.middle);
            match middle.pop_chunk(self.middle_level, side) {
                PopResult::Empty => return None,
                PopResult::Done(chunk) => chunk,
                PopResult::Drained(chunk) => {
                    middle.clear_node();
                    self.middle_level = 0;
                    chunk
                }
            }
        };
        Some(chunk)
    }
}
#[inline]
fn replace_def<A: Default>(dest: &mut A) -> A {
    replace(dest, Default::default())
}
impl<A: Clone> Default for Vector<A> {
    fn default() -> Self {
        Self::new()
    }
}
impl<A: Clone> Clone for Vector<A> {
    fn clone(&self) -> Self {
        match self {
            Empty => Empty,
            Single(chunk) => Single(chunk.clone()),
            Full(tree) => Full(tree.clone()),
        }
    }
}
impl<A: Clone + Debug> Debug for Vector<A> {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        f.debug_list().entries(self.iter()).finish()
        
        
        
        
        
        
        
        
    }
}
#[cfg(not(has_specialisation))]
impl<A: Clone + PartialEq> PartialEq for Vector<A> {
    fn eq(&self, other: &Self) -> bool {
        self.len() == other.len() && self.iter().eq(other.iter())
    }
}
#[cfg(has_specialisation)]
impl<A: Clone + PartialEq> PartialEq for Vector<A> {
    default fn eq(&self, other: &Self) -> bool {
        self.len() == other.len() && self.iter().eq(other.iter())
    }
}
#[cfg(has_specialisation)]
impl<A: Clone + Eq> PartialEq for Vector<A> {
    fn eq(&self, other: &Self) -> bool {
        match (self, other) {
            (Full(left), Full(right)) => {
                if left.length != right.length {
                    return false;
                }
                fn cmp_chunk<A>(left: &Ref<Chunk<A>>, right: &Ref<Chunk<A>>) -> bool {
                    (left.is_empty() && right.is_empty()) || Ref::ptr_eq(left, right)
                }
                if cmp_chunk(&left.outer_f, &right.outer_f)
                    && cmp_chunk(&left.inner_f, &right.inner_f)
                    && cmp_chunk(&left.inner_b, &right.inner_b)
                    && cmp_chunk(&left.outer_b, &right.outer_b)
                    && (left.middle.is_empty() && right.middle.is_empty())
                    || Ref::ptr_eq(&left.middle, &right.middle)
                {
                    return true;
                }
                self.iter().eq(other.iter())
            }
            (left, right) => left.len() == right.len() && left.iter().eq(right.iter()),
        }
    }
}
impl<A: Clone + Eq> Eq for Vector<A> {}
impl<A: Clone + PartialOrd> PartialOrd for Vector<A> {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        self.iter().partial_cmp(other.iter())
    }
}
impl<A: Clone + Ord> Ord for Vector<A> {
    fn cmp(&self, other: &Self) -> Ordering {
        self.iter().cmp(other.iter())
    }
}
impl<A: Clone + Hash> Hash for Vector<A> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        for i in self {
            i.hash(state)
        }
    }
}
impl<A: Clone> Sum for Vector<A> {
    fn sum<I>(it: I) -> Self
    where
        I: Iterator<Item = Self>,
    {
        it.fold(Self::new(), |a, b| a + b)
    }
}
impl<A: Clone> Add for Vector<A> {
    type Output = Vector<A>;
    
    
    
    fn add(mut self, other: Self) -> Self::Output {
        self.append(other);
        self
    }
}
impl<'a, A: Clone> Add for &'a Vector<A> {
    type Output = Vector<A>;
    
    
    
    fn add(self, other: Self) -> Self::Output {
        let mut out = self.clone();
        out.append(other.clone());
        out
    }
}
impl<A: Clone> Extend<A> for Vector<A> {
    
    
    
    fn extend<I>(&mut self, iter: I)
    where
        I: IntoIterator<Item = A>,
    {
        for item in iter {
            self.push_back(item)
        }
    }
}
impl<A: Clone> Index<usize> for Vector<A> {
    type Output = A;
    
    
    
    fn index(&self, index: usize) -> &Self::Output {
        match self.get(index) {
            Some(value) => value,
            None => panic!(
                "Vector::index: index out of bounds: {} < {}",
                index,
                self.len()
            ),
        }
    }
}
impl<A: Clone> IndexMut<usize> for Vector<A> {
    
    
    
    
    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
        match self.get_mut(index) {
            Some(value) => value,
            None => panic!("Vector::index_mut: index out of bounds"),
        }
    }
}
impl<'a, A: Clone> IntoIterator for &'a Vector<A> {
    type Item = &'a A;
    type IntoIter = Iter<'a, A>;
    fn into_iter(self) -> Self::IntoIter {
        self.iter()
    }
}
impl<A: Clone> IntoIterator for Vector<A> {
    type Item = A;
    type IntoIter = ConsumingIter<A>;
    fn into_iter(self) -> Self::IntoIter {
        ConsumingIter::new(self)
    }
}
impl<A: Clone> FromIterator<A> for Vector<A> {
    
    
    
    fn from_iter<I>(iter: I) -> Self
    where
        I: IntoIterator<Item = A>,
    {
        let mut seq = Self::new();
        for item in iter {
            seq.push_back(item)
        }
        seq
    }
}
impl<'s, 'a, A, OA> From<&'s Vector<&'a A>> for Vector<OA>
where
    A: ToOwned<Owned = OA>,
    OA: Borrow<A> + Clone,
{
    fn from(vec: &Vector<&A>) -> Self {
        vec.iter().map(|a| (*a).to_owned()).collect()
    }
}
impl<'a, A: Clone> From<&'a [A]> for Vector<A> {
    fn from(slice: &[A]) -> Self {
        slice.iter().cloned().collect()
    }
}
impl<A: Clone> From<Vec<A>> for Vector<A> {
    
    
    
    
    
    fn from(vec: Vec<A>) -> Self {
        vec.into_iter().collect()
    }
}
impl<'a, A: Clone> From<&'a Vec<A>> for Vector<A> {
    
    
    
    
    
    fn from(vec: &Vec<A>) -> Self {
        vec.iter().cloned().collect()
    }
}
pub struct Iter<'a, A: 'a> {
    focus: Focus<'a, A>,
    front_index: usize,
    back_index: usize,
}
impl<'a, A: Clone> Iter<'a, A> {
    fn new(seq: &'a Vector<A>) -> Self {
        Iter {
            focus: seq.focus(),
            front_index: 0,
            back_index: seq.len(),
        }
    }
    fn from_focus(focus: Focus<'a, A>) -> Self {
        Iter {
            front_index: 0,
            back_index: focus.len(),
            focus,
        }
    }
}
impl<'a, A: Clone> Iterator for Iter<'a, A> {
    type Item = &'a A;
    
    
    
    fn next(&mut self) -> Option<Self::Item> {
        if self.front_index >= self.back_index {
            return None;
        }
        #[allow(unsafe_code)]
        let focus: &'a mut Focus<'a, A> = unsafe { &mut *(&mut self.focus as *mut _) };
        let value = focus.get(self.front_index);
        self.front_index += 1;
        value
    }
    fn size_hint(&self) -> (usize, Option<usize>) {
        let remaining = self.back_index - self.front_index;
        (remaining, Some(remaining))
    }
}
impl<'a, A: Clone> DoubleEndedIterator for Iter<'a, A> {
    
    
    
    fn next_back(&mut self) -> Option<Self::Item> {
        if self.front_index >= self.back_index {
            return None;
        }
        self.back_index -= 1;
        #[allow(unsafe_code)]
        let focus: &'a mut Focus<'a, A> = unsafe { &mut *(&mut self.focus as *mut _) };
        focus.get(self.back_index)
    }
}
impl<'a, A: Clone> ExactSizeIterator for Iter<'a, A> {}
impl<'a, A: Clone> FusedIterator for Iter<'a, A> {}
pub struct IterMut<'a, A>
where
    A: 'a,
{
    focus: FocusMut<'a, A>,
    front_index: usize,
    back_index: usize,
}
impl<'a, A> IterMut<'a, A>
where
    A: 'a + Clone,
{
    fn new(seq: &'a mut Vector<A>) -> Self {
        let focus = seq.focus_mut();
        let len = focus.len();
        IterMut {
            focus,
            front_index: 0,
            back_index: len,
        }
    }
    fn from_focus(focus: FocusMut<'a, A>) -> Self {
        IterMut {
            front_index: 0,
            back_index: focus.len(),
            focus,
        }
    }
}
impl<'a, A> Iterator for IterMut<'a, A>
where
    A: 'a + Clone,
{
    type Item = &'a mut A;
    
    
    
    fn next(&mut self) -> Option<Self::Item> {
        if self.front_index >= self.back_index {
            return None;
        }
        #[allow(unsafe_code)]
        let focus: &'a mut FocusMut<'a, A> = unsafe { &mut *(&mut self.focus as *mut _) };
        let value = focus.get_mut(self.front_index);
        self.front_index += 1;
        value
    }
    fn size_hint(&self) -> (usize, Option<usize>) {
        let remaining = self.back_index - self.front_index;
        (remaining, Some(remaining))
    }
}
impl<'a, A> DoubleEndedIterator for IterMut<'a, A>
where
    A: 'a + Clone,
{
    
    
    
    fn next_back(&mut self) -> Option<Self::Item> {
        if self.front_index >= self.back_index {
            return None;
        }
        self.back_index -= 1;
        #[allow(unsafe_code)]
        let focus: &'a mut FocusMut<'a, A> = unsafe { &mut *(&mut self.focus as *mut _) };
        focus.get_mut(self.back_index)
    }
}
impl<'a, A: Clone> ExactSizeIterator for IterMut<'a, A> {}
impl<'a, A: Clone> FusedIterator for IterMut<'a, A> {}
pub enum ConsumingIter<A> {
    Empty,
    Single(ChunkIter<A>),
    Full(
        Chain<
            Chain<Chain<Chain<ChunkIter<A>, ChunkIter<A>>, ConsumingNodeIter<A>>, ChunkIter<A>>,
            ChunkIter<A>,
        >,
    ),
}
impl<A: Clone> ConsumingIter<A> {
    fn new(seq: Vector<A>) -> Self {
        match seq {
            Empty => ConsumingIter::Empty,
            Single(chunk) => ConsumingIter::Single(clone_ref(chunk).into_iter()),
            Full(tree) => ConsumingIter::Full(tree.into_iter()),
        }
    }
}
impl<A: Clone> Iterator for ConsumingIter<A> {
    type Item = A;
    
    
    
    fn next(&mut self) -> Option<Self::Item> {
        match self {
            ConsumingIter::Empty => None,
            ConsumingIter::Single(iter) => iter.next(),
            ConsumingIter::Full(iter) => iter.next(),
        }
    }
    fn size_hint(&self) -> (usize, Option<usize>) {
        match self {
            ConsumingIter::Empty => (0, Some(0)),
            ConsumingIter::Single(iter) => iter.size_hint(),
            ConsumingIter::Full(iter) => iter.size_hint(),
        }
    }
}
impl<A: Clone> DoubleEndedIterator for ConsumingIter<A> {
    
    
    
    fn next_back(&mut self) -> Option<Self::Item> {
        match self {
            ConsumingIter::Empty => None,
            ConsumingIter::Single(iter) => iter.next_back(),
            ConsumingIter::Full(iter) => iter.next_back(),
        }
    }
}
impl<A: Clone> ExactSizeIterator for ConsumingIter<A> {}
impl<A: Clone> FusedIterator for ConsumingIter<A> {}
pub struct Chunks<'a, A: 'a> {
    focus: Focus<'a, A>,
    front_index: usize,
    back_index: usize,
}
impl<'a, A: Clone> Chunks<'a, A> {
    fn new(seq: &'a Vector<A>) -> Self {
        Chunks {
            focus: seq.focus(),
            front_index: 0,
            back_index: seq.len(),
        }
    }
}
impl<'a, A: Clone> Iterator for Chunks<'a, A> {
    type Item = &'a [A];
    
    
    
    fn next(&mut self) -> Option<Self::Item> {
        if self.front_index >= self.back_index {
            return None;
        }
        #[allow(unsafe_code)]
        let focus: &'a mut Focus<'a, A> = unsafe { &mut *(&mut self.focus as *mut _) };
        let (range, value) = focus.chunk_at(self.front_index);
        self.front_index = range.end;
        Some(value)
    }
}
impl<'a, A: Clone> DoubleEndedIterator for Chunks<'a, A> {
    
    
    
    fn next_back(&mut self) -> Option<Self::Item> {
        if self.front_index >= self.back_index {
            return None;
        }
        self.back_index -= 1;
        #[allow(unsafe_code)]
        let focus: &'a mut Focus<'a, A> = unsafe { &mut *(&mut self.focus as *mut _) };
        let (range, value) = focus.chunk_at(self.back_index);
        self.back_index = range.start;
        Some(value)
    }
}
impl<'a, A: Clone> FusedIterator for Chunks<'a, A> {}
pub struct ChunksMut<'a, A: 'a> {
    focus: FocusMut<'a, A>,
    front_index: usize,
    back_index: usize,
}
impl<'a, A: Clone> ChunksMut<'a, A> {
    fn new(seq: &'a mut Vector<A>) -> Self {
        let len = seq.len();
        ChunksMut {
            focus: seq.focus_mut(),
            front_index: 0,
            back_index: len,
        }
    }
}
impl<'a, A: Clone> Iterator for ChunksMut<'a, A> {
    type Item = &'a mut [A];
    
    
    
    fn next(&mut self) -> Option<Self::Item> {
        if self.front_index >= self.back_index {
            return None;
        }
        #[allow(unsafe_code)]
        let focus: &'a mut FocusMut<'a, A> = unsafe { &mut *(&mut self.focus as *mut _) };
        let (range, value) = focus.chunk_at(self.front_index);
        self.front_index = range.end;
        Some(value)
    }
}
impl<'a, A: Clone> DoubleEndedIterator for ChunksMut<'a, A> {
    
    
    
    fn next_back(&mut self) -> Option<Self::Item> {
        if self.front_index >= self.back_index {
            return None;
        }
        self.back_index -= 1;
        #[allow(unsafe_code)]
        let focus: &'a mut FocusMut<'a, A> = unsafe { &mut *(&mut self.focus as *mut _) };
        let (range, value) = focus.chunk_at(self.back_index);
        self.back_index = range.start;
        Some(value)
    }
}
impl<'a, A: Clone> FusedIterator for ChunksMut<'a, A> {}
#[cfg(all(threadsafe, any(test, feature = "rayon")))]
pub mod rayon {
    use super::*;
    use ::rayon::iter::plumbing::{
        bridge, Consumer, Producer, ProducerCallback, UnindexedConsumer,
    };
    use ::rayon::iter::{
        IndexedParallelIterator, IntoParallelRefIterator, IntoParallelRefMutIterator,
        ParallelIterator,
    };
    impl<'a, A> IntoParallelRefIterator<'a> for Vector<A>
    where
        A: Clone + Send + Sync + 'a,
    {
        type Item = &'a A;
        type Iter = ParIter<'a, A>;
        fn par_iter(&'a self) -> Self::Iter {
            ParIter {
                focus: self.focus(),
            }
        }
    }
    impl<'a, A> IntoParallelRefMutIterator<'a> for Vector<A>
    where
        A: Clone + Send + Sync + 'a,
    {
        type Item = &'a mut A;
        type Iter = ParIterMut<'a, A>;
        fn par_iter_mut(&'a mut self) -> Self::Iter {
            ParIterMut {
                focus: self.focus_mut(),
            }
        }
    }
    pub struct ParIter<'a, A>
    where
        A: Clone + Send + Sync + 'a,
    {
        focus: Focus<'a, A>,
    }
    impl<'a, A> ParallelIterator for ParIter<'a, A>
    where
        A: Clone + Send + Sync + 'a,
    {
        type Item = &'a A;
        fn drive_unindexed<C>(self, consumer: C) -> C::Result
        where
            C: UnindexedConsumer<Self::Item>,
        {
            bridge(self, consumer)
        }
    }
    impl<'a, A> IndexedParallelIterator for ParIter<'a, A>
    where
        A: Clone + Send + Sync + 'a,
    {
        fn drive<C>(self, consumer: C) -> C::Result
        where
            C: Consumer<Self::Item>,
        {
            bridge(self, consumer)
        }
        fn len(&self) -> usize {
            self.focus.len()
        }
        fn with_producer<CB>(self, callback: CB) -> CB::Output
        where
            CB: ProducerCallback<Self::Item>,
        {
            callback.callback(VectorProducer { focus: self.focus })
        }
    }
    pub struct ParIterMut<'a, A>
    where
        A: Clone + Send + Sync + 'a,
    {
        focus: FocusMut<'a, A>,
    }
    impl<'a, A> ParallelIterator for ParIterMut<'a, A>
    where
        A: Clone + Send + Sync + 'a,
    {
        type Item = &'a mut A;
        fn drive_unindexed<C>(self, consumer: C) -> C::Result
        where
            C: UnindexedConsumer<Self::Item>,
        {
            bridge(self, consumer)
        }
    }
    impl<'a, A> IndexedParallelIterator for ParIterMut<'a, A>
    where
        A: Clone + Send + Sync + 'a,
    {
        fn drive<C>(self, consumer: C) -> C::Result
        where
            C: Consumer<Self::Item>,
        {
            bridge(self, consumer)
        }
        fn len(&self) -> usize {
            self.focus.len()
        }
        fn with_producer<CB>(self, callback: CB) -> CB::Output
        where
            CB: ProducerCallback<Self::Item>,
        {
            callback.callback(VectorMutProducer { focus: self.focus })
        }
    }
    struct VectorProducer<'a, A>
    where
        A: Clone + Send + Sync + 'a,
    {
        focus: Focus<'a, A>,
    }
    impl<'a, A> Producer for VectorProducer<'a, A>
    where
        A: Clone + Send + Sync + 'a,
    {
        type Item = &'a A;
        type IntoIter = Iter<'a, A>;
        fn into_iter(self) -> Self::IntoIter {
            self.focus.into_iter()
        }
        fn split_at(self, index: usize) -> (Self, Self) {
            let (left, right) = self.focus.split_at(index);
            (
                VectorProducer { focus: left },
                VectorProducer { focus: right },
            )
        }
    }
    struct VectorMutProducer<'a, A>
    where
        A: Clone + Send + Sync + 'a,
    {
        focus: FocusMut<'a, A>,
    }
    impl<'a, A> Producer for VectorMutProducer<'a, A>
    where
        A: Clone + Send + Sync + 'a,
    {
        type Item = &'a mut A;
        type IntoIter = IterMut<'a, A>;
        fn into_iter(self) -> Self::IntoIter {
            self.focus.into_iter()
        }
        fn split_at(self, index: usize) -> (Self, Self) {
            let (left, right) = self.focus.split_at(index);
            (
                VectorMutProducer { focus: left },
                VectorMutProducer { focus: right },
            )
        }
    }
    #[cfg(test)]
    mod test {
        use super::super::*;
        use super::proptest::vector;
        use ::proptest::num::i32;
        use ::proptest::proptest;
        use ::rayon::iter::{
            IntoParallelRefIterator, IntoParallelRefMutIterator, ParallelIterator,
        };
        proptest! {
            #[test]
            fn par_iter(ref mut input in vector(i32::ANY, 0..10000)) {
                assert_eq!(input.iter().max(), input.par_iter().max())
            }
            #[test]
            fn par_mut_iter(ref mut input in vector(i32::ANY, 0..10000)) {
                let mut vec = input.clone();
                vec.par_iter_mut().for_each(|i| *i = i.overflowing_add(1).0);
                let expected: Vector<i32> = input.clone().into_iter().map(|i| i.overflowing_add(1).0).collect();
                assert_eq!(expected, vec);
            }
        }
    }
}
#[cfg(all(threadsafe, feature = "quickcheck"))]
use quickcheck::{Arbitrary, Gen};
#[cfg(all(threadsafe, feature = "quickcheck"))]
impl<A: Arbitrary + Sync + Clone> Arbitrary for Vector<A> {
    fn arbitrary<G: Gen>(g: &mut G) -> Self {
        Vector::from_iter(Vec::<A>::arbitrary(g))
    }
}
#[cfg(any(test, feature = "proptest"))]
pub mod proptest {
    use super::*;
    use ::proptest::collection::vec;
    use ::proptest::strategy::{BoxedStrategy, Strategy, ValueTree};
    use std::ops::Range;
    
    
    
    
    
    
    
    
    
    
    
    
    
    pub fn vector<A: Strategy + 'static>(
        element: A,
        size: Range<usize>,
    ) -> BoxedStrategy<Vector<<A::Tree as ValueTree>::Value>>
    where
        <A::Tree as ValueTree>::Value: Clone,
    {
        vec(element, size).prop_map(Vector::from_iter).boxed()
    }
}
#[cfg(test)]
mod test {
    use super::proptest::vector;
    use super::*;
    use ::proptest::collection::vec;
    use ::proptest::num::{i32, usize};
    use ::proptest::proptest;
    #[test]
    fn macro_allows_trailing_comma() {
        let vec1 = vector![1, 2, 3];
        let vec2 = vector![1, 2, 3,];
        assert_eq!(vec1, vec2);
    }
    #[test]
    fn indexing() {
        let vec1 = vector![0, 1, 2, 3, 4, 5];
        let mut vec2 = vec1.clone();
        vec2.push_front(0);
        assert_eq!(0, *vec2.get(0).unwrap());
        assert_eq!(0, vec2[0]);
    }
    #[test]
    fn large_vector_focus() {
        let input = Vector::from_iter(0..100_000);
        let vec = input.clone();
        let mut sum: i64 = 0;
        let mut focus = vec.focus();
        for i in 0..input.len() {
            sum += *focus.index(i);
        }
        let expected: i64 = (0..100_000).sum();
        assert_eq!(expected, sum);
    }
    #[test]
    fn large_vector_focus_mut() {
        let input = Vector::from_iter(0..100_000);
        let mut vec = input.clone();
        {
            let mut focus = vec.focus_mut();
            for i in 0..input.len() {
                let p = focus.index_mut(i);
                *p += 1;
            }
        }
        let expected: Vector<i32> = input.clone().into_iter().map(|i| i + 1).collect();
        assert_eq!(expected, vec);
    }
    #[test]
    fn issue_55_fwd() {
        let mut l = Vector::new();
        for i in 0..4098 {
            l.append(Vector::unit(i));
        }
        l.append(Vector::unit(4098));
        assert_eq!(Some(&4097), l.get(4097));
        assert_eq!(Some(&4096), l.get(4096));
    }
    #[test]
    fn issue_55_back() {
        let mut l = Vector::unit(0);
        for i in 0..4099 {
            let mut tmp = Vector::unit(i + 1);
            tmp.append(l);
            l = tmp;
        }
        assert_eq!(Some(&4098), l.get(1));
        assert_eq!(Some(&4097), l.get(2));
        let len = l.len();
        l.slice(2..len);
    }
    #[test]
    fn issue_55_append() {
        let mut vec1 = Vector::from_iter(0..92);
        let vec2 = Vector::from_iter(0..165);
        vec1.append(vec2);
    }
    #[test]
    fn issue_70() {
        let mut x = Vector::new();
        for _ in 0..262 {
            x.push_back(0);
        }
        for _ in 0..97 {
            x.pop_front();
        }
        for &offset in &[160, 163, 160] {
            x.remove(offset);
        }
        for _ in 0..64 {
            x.push_back(0);
        }
        
        
        
        match x {
            Vector::Full(ref tree) => {
                assert_eq!(129, tree.middle.len());
                assert_eq!(3, tree.middle.number_of_children());
            }
            _ => unreachable!(),
        }
        x.push_back(0);
        match x {
            Vector::Full(ref tree) => {
                assert_eq!(131, tree.middle.len());
                assert_eq!(3, tree.middle.number_of_children())
            }
            _ => unreachable!(),
        }
        for _ in 0..64 {
            x.push_back(0);
        }
        for _ in x.iter() {}
    }
    #[test]
    fn issue_67() {
        let mut l = Vector::unit(4100);
        for i in (0..4099).rev() {
            let mut tmp = Vector::unit(i);
            tmp.append(l);
            l = tmp;
        }
        assert_eq!(4100, l.len());
        let len = l.len();
        let tail = l.slice(1..len);
        assert_eq!(1, l.len());
        assert_eq!(4099, tail.len());
        assert_eq!(Some(&0), l.get(0));
        assert_eq!(Some(&1), tail.get(0));
    }
    #[test]
    fn issue_74_simple_size() {
        use crate::nodes::rrb::NODE_SIZE;
        let mut x = Vector::new();
        for _ in 0..(CHUNK_SIZE
            * (
                1 
                + (2 * NODE_SIZE) 
                + 1 
                + 1
                
            ))
        {
            x.push_back(0u32);
        }
        let middle_first_node_start = CHUNK_SIZE;
        let middle_second_node_start = middle_first_node_start + NODE_SIZE * CHUNK_SIZE;
        
        x.remove(middle_second_node_start);
        
        
        
        x.push_back(0u32);
        match x {
            Vector::Full(tree) => {
                assert_eq!(3, tree.middle.number_of_children());
                assert_eq!(
                    2 * NODE_SIZE * CHUNK_SIZE + CHUNK_SIZE - 1,
                    tree.middle.len()
                );
            }
            _ => unreachable!(),
        }
    }
    #[test]
    fn issue_77() {
        let mut x = Vector::new();
        for _ in 0..44 { x.push_back(0); }
        for _ in 0..20 { x.insert(0, 0); }
        x.insert(1, 0);
        for _ in 0..441 { x.push_back(0); }
        for _ in 0..58 { x.insert(0, 0); }
        x.insert(514, 0);
        for _ in 0..73 { x.push_back(0); }
        for _ in 0..10 { x.insert(0, 0); }
        x.insert(514, 0);
    }
    proptest! {
        #[test]
        fn iter(ref vec in vec(i32::ANY, 0..1000)) {
            let seq: Vector<i32> = Vector::from_iter(vec.iter().cloned());
            for (index, item) in seq.iter().enumerate() {
                assert_eq!(&vec[index], item);
            }
            assert_eq!(vec.len(), seq.len());
        }
        #[test]
        fn push_front_mut(ref input in vec(i32::ANY, 0..1000)) {
            let mut vector = Vector::new();
            for (count, value) in input.iter().cloned().enumerate() {
                assert_eq!(count, vector.len());
                vector.push_front(value);
                assert_eq!(count + 1, vector.len());
            }
            let input2 = Vec::from_iter(input.iter().rev().cloned());
            assert_eq!(input2, Vec::from_iter(vector.iter().cloned()));
        }
        #[test]
        fn push_back_mut(ref input in vec(i32::ANY, 0..1000)) {
            let mut vector = Vector::new();
            for (count, value) in input.iter().cloned().enumerate() {
                assert_eq!(count, vector.len());
                vector.push_back(value);
                assert_eq!(count + 1, vector.len());
            }
            assert_eq!(input, &Vec::from_iter(vector.iter().cloned()));
        }
        #[test]
        fn pop_back_mut(ref input in vec(i32::ANY, 0..1000)) {
            let mut vector = Vector::from_iter(input.iter().cloned());
            assert_eq!(input.len(), vector.len());
            for (index, value) in input.iter().cloned().enumerate().rev() {
                match vector.pop_back() {
                    None => panic!("vector emptied unexpectedly"),
                    Some(item) => {
                        assert_eq!(index, vector.len());
                        assert_eq!(value, item);
                    }
                }
            }
            assert_eq!(0, vector.len());
        }
        #[test]
        fn pop_front_mut(ref input in vec(i32::ANY, 0..1000)) {
            let mut vector = Vector::from_iter(input.iter().cloned());
            assert_eq!(input.len(), vector.len());
            for (index, value) in input.iter().cloned().rev().enumerate().rev() {
                match vector.pop_front() {
                    None => panic!("vector emptied unexpectedly"),
                    Some(item) => {
                        assert_eq!(index, vector.len());
                        assert_eq!(value, item);
                    }
                }
            }
            assert_eq!(0, vector.len());
        }
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        #[test]
        fn split(ref vec in vec(i32::ANY, 1..2000), split_pos in usize::ANY) {
            let split_index = split_pos % (vec.len() + 1);
            let mut left = Vector::from_iter(vec.iter().cloned());
            let right = left.split_off(split_index);
            assert_eq!(left.len(), split_index);
            assert_eq!(right.len(), vec.len() - split_index);
            for (index, item) in left.iter().enumerate() {
                assert_eq!(& vec[index], item);
            }
            for (index, item) in right.iter().enumerate() {
                assert_eq!(&vec[split_index + index], item);
            }
        }
        #[test]
        fn append(ref vec1 in vec(i32::ANY, 0..1000), ref vec2 in vec(i32::ANY, 0..1000)) {
            let mut seq1 = Vector::from_iter(vec1.iter().cloned());
            let seq2 = Vector::from_iter(vec2.iter().cloned());
            assert_eq!(seq1.len(), vec1.len());
            assert_eq!(seq2.len(), vec2.len());
            seq1.append(seq2);
            let mut vec = vec1.clone();
            vec.extend(vec2);
            assert_eq!(seq1.len(), vec.len());
            for (index, item) in seq1.into_iter().enumerate() {
                assert_eq!(vec[index], item);
            }
        }
        #[test]
        fn iter_mut(ref input in vector(i32::ANY, 0..10000)) {
            let mut vec = input.clone();
            {
                for p in vec.iter_mut() {
                    *p = p.overflowing_add(1).0;
                }
            }
            let expected: Vector<i32> = input.clone().into_iter().map(|i| i.overflowing_add(1).0).collect();
            assert_eq!(expected, vec);
        }
        #[test]
        fn focus(ref input in vector(i32::ANY, 0..10000)) {
            let mut vec = input.clone();
            {
                let mut focus = vec.focus_mut();
                for i in 0..input.len() {
                    let p = focus.index_mut(i);
                    *p = p.overflowing_add(1).0;
                }
            }
            let expected: Vector<i32> = input.clone().into_iter().map(|i| i.overflowing_add(1).0).collect();
            assert_eq!(expected, vec);
        }
        #[test]
        fn focus_mut_split(ref input in vector(i32::ANY, 0..10000)) {
            let mut vec = input.clone();
            fn split_down(focus: FocusMut<'_, i32>) {
                let len = focus.len();
                if len < 8 {
                    for p in focus {
                        *p = p.overflowing_add(1).0;
                    }
                } else {
                    let (left, right) = focus.split_at(len / 2);
                    split_down(left);
                    split_down(right);
                }
            }
            split_down(vec.focus_mut());
            let expected: Vector<i32> = input.clone().into_iter().map(|i| i.overflowing_add(1).0).collect();
            assert_eq!(expected, vec);
        }
        #[test]
        fn chunks(ref input in vector(i32::ANY, 0..10000)) {
            let output: Vector<_> = input.leaves().flat_map(|a|a).cloned().collect();
            assert_eq!(input, &output);
            let rev_in: Vector<_> = input.iter().rev().cloned().collect();
            let rev_out: Vector<_> = input.leaves().rev().map(|c| c.iter().rev()).flat_map(|a|a).cloned().collect();
            assert_eq!(rev_in, rev_out);
        }
        #[test]
        fn chunks_mut(ref mut input_src in vector(i32::ANY, 0..10000)) {
            let mut input = input_src.clone();
            #[allow(clippy::map_clone)]
            let output: Vector<_> = input.leaves_mut().flat_map(|a| a).map(|v| *v).collect();
            assert_eq!(input, output);
            let rev_in: Vector<_> = input.iter().rev().cloned().collect();
            let rev_out: Vector<_> = input.leaves_mut().rev().map(|c| c.iter().rev()).flat_map(|a|a).cloned().collect();
            assert_eq!(rev_in, rev_out);
        }
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
    }
}