#![cfg(feature = "alloc")]

use super::*;

use alloc::vec::{self, Vec};
use tinyvec_macros::impl_mirrored;

#[cfg(feature = "serde")]
use core::marker::PhantomData;
#[cfg(feature = "serde")]
use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor};
#[cfg(feature = "serde")]
use serde::ser::{Serialize, SerializeSeq, Serializer};

/// Helper to make a `TinyVec`.
///
/// You specify the backing array type, and optionally give all the elements you
/// want to initially place into the array.
///
/// ```rust
/// use tinyvec::*;
///
/// // The backing array type can be specified in the macro call
/// let empty_tv = tiny_vec!([u8; 16]);
/// let some_ints = tiny_vec!([i32; 4] => 1, 2, 3);
/// let many_ints = tiny_vec!([i32; 4] => 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
///
/// // Or left to inference
/// let empty_tv: TinyVec<[u8; 16]> = tiny_vec!();
/// let some_ints: TinyVec<[i32; 4]> = tiny_vec!(1, 2, 3);
/// let many_ints: TinyVec<[i32; 4]> = tiny_vec!(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
/// ```
#[macro_export]
#[cfg_attr(docs_rs, doc(cfg(feature = "alloc")))]
macro_rules! tiny_vec {
  ($array_type:ty => $($elem:expr),* $(,)?) => {
    {
      // https://github.com/rust-lang/lang-team/issues/28
      const INVOKED_ELEM_COUNT: usize = 0 $( + { let _ = stringify!($elem); 1 })*;
      // If we have more `$elem` than the `CAPACITY` we will simply go directly
      // to constructing on the heap.
      match $crate::TinyVec::constructor_for_capacity(INVOKED_ELEM_COUNT) {
        $crate::TinyVecConstructor::Inline(f) => {
          f($crate::array_vec!($array_type => $($elem),*))
        }
        $crate::TinyVecConstructor::Heap(f) => {
          f(vec!($($elem),*))
        }
      }
    }
  };
  ($array_type:ty) => {
    $crate::TinyVec::<$array_type>::default()
  };
  ($($elem:expr),*) => {
    $crate::tiny_vec!(_ => $($elem),*)
  };
  ($elem:expr; $n:expr) => {
    $crate::TinyVec::from([$elem; $n])
  };
  () => {
    $crate::tiny_vec!(_)
  };
}

#[doc(hidden)] // Internal implementation details of `tiny_vec!`
pub enum TinyVecConstructor<A: Array> {
  Inline(fn(ArrayVec<A>) -> TinyVec<A>),
  Heap(fn(Vec<A::Item>) -> TinyVec<A>),
}

/// A vector that starts inline, but can automatically move to the heap.
///
/// * Requires the `alloc` feature
///
/// A `TinyVec` is either an Inline([`ArrayVec`](crate::ArrayVec::<A>)) or
/// Heap([`Vec`](https://doc.rust-lang.org/alloc/vec/struct.Vec.html)). The
/// interface for the type as a whole is a bunch of methods that just match on
/// the enum variant and then call the same method on the inner vec.
///
/// ## Construction
///
/// Because it's an enum, you can construct a `TinyVec` simply by making an
/// `ArrayVec` or `Vec` and then putting it into the enum.
///
/// There is also a macro
///
/// ```rust
/// # use tinyvec::*;
/// let empty_tv = tiny_vec!([u8; 16]);
/// let some_ints = tiny_vec!([i32; 4] => 1, 2, 3);
/// ```
#[derive(Clone)]
#[cfg_attr(docs_rs, doc(cfg(feature = "alloc")))]
pub enum TinyVec<A: Array> {
  #[allow(missing_docs)]
  Inline(ArrayVec<A>),
  #[allow(missing_docs)]
  Heap(Vec<A::Item>),
}

impl<A: Array> Default for TinyVec<A> {
  #[inline]
  #[must_use]
  fn default() -> Self {
    TinyVec::Inline(ArrayVec::default())
  }
}

impl<A: Array> Deref for TinyVec<A> {
  type Target = [A::Item];

  impl_mirrored! {
    type Mirror = TinyVec;
    #[inline(always)]
    #[must_use]
    fn deref(self: &Self) -> &Self::Target;
  }
}

impl<A: Array> DerefMut for TinyVec<A> {
  impl_mirrored! {
    type Mirror = TinyVec;
    #[inline(always)]
    #[must_use]
    fn deref_mut(self: &mut Self) -> &mut Self::Target;
  }
}

impl<A: Array, I: SliceIndex<[A::Item]>> Index<I> for TinyVec<A> {
  type Output = <I as SliceIndex<[A::Item]>>::Output;
  #[inline(always)]
  #[must_use]
  fn index(&self, index: I) -> &Self::Output {
    &self.deref()[index]
  }
}

impl<A: Array, I: SliceIndex<[A::Item]>> IndexMut<I> for TinyVec<A> {
  #[inline(always)]
  #[must_use]
  fn index_mut(&mut self, index: I) -> &mut Self::Output {
    &mut self.deref_mut()[index]
  }
}

#[cfg(feature = "serde")]
#[cfg_attr(docs_rs, doc(cfg(feature = "serde")))]
impl<A: Array> Serialize for TinyVec<A>
where
  A::Item: Serialize,
{
  #[must_use]
  fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
  where
    S: Serializer,
  {
    let mut seq = serializer.serialize_seq(Some(self.len()))?;
    for element in self.iter() {
      seq.serialize_element(element)?;
    }
    seq.end()
  }
}

#[cfg(feature = "serde")]
#[cfg_attr(docs_rs, doc(cfg(feature = "serde")))]
impl<'de, A: Array> Deserialize<'de> for TinyVec<A>
where
  A::Item: Deserialize<'de>,
{
  fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
  where
    D: Deserializer<'de>,
  {
    deserializer.deserialize_seq(TinyVecVisitor(PhantomData))
  }
}

impl<A: Array> TinyVec<A> {
  /// Returns whether elements are on heap
  #[inline(always)]
  #[must_use]
  pub fn is_heap(&self) -> bool {
    match self {
      TinyVec::Heap(_) => true,
      TinyVec::Inline(_) => false,
    }
  }
  /// Returns whether elements are on stack
  #[inline(always)]
  #[must_use]
  pub fn is_inline(&self) -> bool {
    !self.is_heap()
  }

  /// Shrinks the capacity of the vector as much as possible.\
  /// It is inlined if length is less than `A::CAPACITY`.
  /// ```rust
  /// use tinyvec::*;
  /// let mut tv = tiny_vec!([i32; 2] => 1, 2, 3);
  /// assert!(tv.is_heap());
  /// let _ = tv.pop();
  /// assert!(tv.is_heap());
  /// tv.shrink_to_fit();
  /// assert!(tv.is_inline());
  /// ```
  pub fn shrink_to_fit(&mut self) {
    let vec = match self {
      TinyVec::Inline(_) => return,
      TinyVec::Heap(h) => h,
    };

    if vec.len() > A::CAPACITY {
      return vec.shrink_to_fit();
    }

    let moved_vec = core::mem::replace(vec, Vec::new());

    let mut av = ArrayVec::default();
    let mut rest = av.fill(moved_vec);
    debug_assert!(rest.next().is_none());
    *self = TinyVec::Inline(av);
  }

  /// Moves the content of the TinyVec to the heap, if it's inline.
  /// ```rust
  /// use tinyvec::*;
  /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3);
  /// assert!(tv.is_inline());
  /// tv.move_to_the_heap();
  /// assert!(tv.is_heap());
  /// ```
  #[allow(clippy::missing_inline_in_public_items)]
  pub fn move_to_the_heap(&mut self) {
    let arr = match self {
      TinyVec::Heap(_) => return,
      TinyVec::Inline(a) => a,
    };

    let v = arr.drain_to_vec();
    *self = TinyVec::Heap(v);
  }

  /// If TinyVec is inline, moves the content of it to the heap.
  /// Also reserves additional space.
  /// ```rust
  /// use tinyvec::*;
  /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3);
  /// assert!(tv.is_inline());
  /// tv.move_to_the_heap_and_reserve(32);
  /// assert!(tv.is_heap());
  /// assert!(tv.capacity() >= 35);
  /// ```
  pub fn move_to_the_heap_and_reserve(&mut self, n: usize) {
    let arr = match self {
      TinyVec::Heap(h) => return h.reserve(n),
      TinyVec::Inline(a) => a,
    };

    let v = arr.drain_to_vec_and_reserve(n);
    *self = TinyVec::Heap(v);
  }

  /// Reserves additional space.
  /// Moves to the heap if array can't hold `n` more items
  /// ```rust
  /// use tinyvec::*;
  /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3, 4);
  /// assert!(tv.is_inline());
  /// tv.reserve(1);
  /// assert!(tv.is_heap());
  /// assert!(tv.capacity() >= 5);
  /// ```
  pub fn reserve(&mut self, n: usize) {
    let arr = match self {
      TinyVec::Heap(h) => return h.reserve(n),
      TinyVec::Inline(a) => a,
    };

    if n > arr.capacity() - arr.len() {
      let v = arr.drain_to_vec_and_reserve(n);
      *self = TinyVec::Heap(v);
    }

    /* In this place array has enough place, so no work is needed more */
    return;
  }

  /// Reserves additional space.
  /// Moves to the heap if array can't hold `n` more items
  ///
  /// From [Vec::reserve_exact](https://doc.rust-lang.org/std/vec/struct.Vec.html#method.reserve_exact)
  /// ```text
  /// Note that the allocator may give the collection more space than it requests.
  /// Therefore, capacity can not be relied upon to be precisely minimal.
  /// Prefer `reserve` if future insertions are expected.
  /// ```
  /// ```rust
  /// use tinyvec::*;
  /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3, 4);
  /// assert!(tv.is_inline());
  /// tv.reserve_exact(1);
  /// assert!(tv.is_heap());
  /// assert!(tv.capacity() >= 5);
  /// ```
  pub fn reserve_exact(&mut self, n: usize) {
    let arr = match self {
      TinyVec::Heap(h) => return h.reserve_exact(n),
      TinyVec::Inline(a) => a,
    };

    if n > arr.capacity() - arr.len() {
      let v = arr.drain_to_vec_and_reserve(n);
      *self = TinyVec::Heap(v);
    }

    /* In this place array has enough place, so no work is needed more */
    return;
  }

  /// Makes a new TinyVec with _at least_ the given capacity.
  ///
  /// If the requested capacity is less than or equal to the array capacity you
  /// get an inline vec. If it's greater than you get a heap vec.
  /// ```
  /// # use tinyvec::*;
  /// let t = TinyVec::<[u8; 10]>::with_capacity(5);
  /// assert!(t.is_inline());
  /// assert!(t.capacity() >= 5);
  ///
  /// let t = TinyVec::<[u8; 10]>::with_capacity(20);
  /// assert!(t.is_heap());
  /// assert!(t.capacity() >= 20);
  /// ```
  #[inline]
  #[must_use]
  pub fn with_capacity(cap: usize) -> Self {
    if cap <= A::CAPACITY {
      TinyVec::Inline(ArrayVec::default())
    } else {
      TinyVec::Heap(Vec::with_capacity(cap))
    }
  }
}

impl<A: Array> TinyVec<A> {
  /// Move all values from `other` into this vec.
  #[cfg(feature = "rustc_1_40")]
  #[inline]
  pub fn append(&mut self, other: &mut Self) {
    self.reserve(other.len());

    /* Doing append should be faster, because it is effectively a memcpy */
    match (self, other) {
      (TinyVec::Heap(sh), TinyVec::Heap(oh)) => sh.append(oh),
      (TinyVec::Inline(a), TinyVec::Heap(h)) => a.extend(h.drain(..)),
      (ref mut this, TinyVec::Inline(arr)) => this.extend(arr.drain(..)),
    }
  }

  /// Move all values from `other` into this vec.
  #[cfg(not(feature = "rustc_1_40"))]
  #[inline]
  pub fn append(&mut self, other: &mut Self) {
    match other {
      TinyVec::Inline(a) => self.extend(a.drain(..)),
      TinyVec::Heap(h) => self.extend(h.drain(..)),
    }
  }

  impl_mirrored! {
    type Mirror = TinyVec;

    /// Remove an element, swapping the end of the vec into its place.
    ///
    /// ## Panics
    /// * If the index is out of bounds.
    ///
    /// ## Example
    /// ```rust
    /// use tinyvec::*;
    /// let mut tv = tiny_vec!([&str; 4] => "foo", "bar", "quack", "zap");
    ///
    /// assert_eq!(tv.swap_remove(1), "bar");
    /// assert_eq!(tv.as_slice(), &["foo", "zap", "quack"][..]);
    ///
    /// assert_eq!(tv.swap_remove(0), "foo");
    /// assert_eq!(tv.as_slice(), &["quack", "zap"][..]);
    /// ```
    #[inline]
    pub fn swap_remove(self: &mut Self, index: usize) -> A::Item;

    /// Remove and return the last element of the vec, if there is one.
    ///
    /// ## Failure
    /// * If the vec is empty you get `None`.
    #[inline]
    pub fn pop(self: &mut Self) -> Option<A::Item>;

    /// Removes the item at `index`, shifting all others down by one index.
    ///
    /// Returns the removed element.
    ///
    /// ## Panics
    ///
    /// If the index is out of bounds.
    ///
    /// ## Example
    ///
    /// ```rust
    /// use tinyvec::*;
    /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3);
    /// assert_eq!(tv.remove(1), 2);
    /// assert_eq!(tv.as_slice(), &[1, 3][..]);
    /// ```
    #[inline]
    pub fn remove(self: &mut Self, index: usize) -> A::Item;

    /// The length of the vec (in elements).
    #[inline(always)]
    #[must_use]
    pub fn len(self: &Self) -> usize;

    /// The capacity of the `TinyVec`.
    ///
    /// When not heap allocated this is fixed based on the array type.
    /// Otherwise its the result of the underlying Vec::capacity.
    #[inline(always)]
    #[must_use]
    pub fn capacity(self: &Self) -> usize;

    /// Reduces the vec's length to the given value.
    ///
    /// If the vec is already shorter than the input, nothing happens.
    #[inline]
    pub fn truncate(self: &mut Self, new_len: usize);

    /// A mutable pointer to the backing array.
    ///
    /// ## Safety
    ///
    /// This pointer has provenance over the _entire_ backing array/buffer.
    #[inline(always)]
    #[must_use]
    pub fn as_mut_ptr(self: &mut Self) -> *mut A::Item;

    /// A const pointer to the backing array.
    ///
    /// ## Safety
    ///
    /// This pointer has provenance over the _entire_ backing array/buffer.
    #[inline(always)]
    #[must_use]
    pub fn as_ptr(self: &Self) -> *const A::Item;
  }

  /// Walk the vec and keep only the elements that pass the predicate given.
  ///
  /// ## Example
  ///
  /// ```rust
  /// use tinyvec::*;
  ///
  /// let mut tv = tiny_vec!([i32; 10] => 1, 2, 3, 4);
  /// tv.retain(|&x| x % 2 == 0);
  /// assert_eq!(tv.as_slice(), &[2, 4][..]);
  /// ```
  #[inline]
  pub fn retain<F: FnMut(&A::Item) -> bool>(self: &mut Self, acceptable: F) {
    match self {
      TinyVec::Inline(i) => i.retain(acceptable),
      TinyVec::Heap(h) => h.retain(acceptable),
    }
  }

  /// Helper for getting the mut slice.
  #[inline(always)]
  #[must_use]
  pub fn as_mut_slice(self: &mut Self) -> &mut [A::Item] {
    self.deref_mut()
  }

  /// Helper for getting the shared slice.
  #[inline(always)]
  #[must_use]
  pub fn as_slice(self: &Self) -> &[A::Item] {
    self.deref()
  }

  /// Removes all elements from the vec.
  #[inline(always)]
  pub fn clear(&mut self) {
    self.truncate(0)
  }

  /// De-duplicates the vec.
  #[cfg(feature = "nightly_slice_partition_dedup")]
  #[inline(always)]
  pub fn dedup(&mut self)
  where
    A::Item: PartialEq,
  {
    self.dedup_by(|a, b| a == b)
  }

  /// De-duplicates the vec according to the predicate given.
  #[cfg(feature = "nightly_slice_partition_dedup")]
  #[inline(always)]
  pub fn dedup_by<F>(&mut self, same_bucket: F)
  where
    F: FnMut(&mut A::Item, &mut A::Item) -> bool,
  {
    let len = {
      let (dedup, _) = self.as_mut_slice().partition_dedup_by(same_bucket);
      dedup.len()
    };
    self.truncate(len);
  }

  /// De-duplicates the vec according to the key selector given.
  #[cfg(feature = "nightly_slice_partition_dedup")]
  #[inline(always)]
  pub fn dedup_by_key<F, K>(&mut self, mut key: F)
  where
    F: FnMut(&mut A::Item) -> K,
    K: PartialEq,
  {
    self.dedup_by(|a, b| key(a) == key(b))
  }

  /// Creates a draining iterator that removes the specified range in the vector
  /// and yields the removed items.
  ///
  /// **Note: This method has significant performance issues compared to
  /// matching on the TinyVec and then calling drain on the Inline or Heap value
  /// inside. The draining iterator has to branch on every single access. It is
  /// provided for simplicity and compatability only.**
  ///
  /// ## Panics
  /// * If the start is greater than the end
  /// * If the end is past the edge of the vec.
  ///
  /// ## Example
  /// ```rust
  /// use tinyvec::*;
  /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3);
  /// let tv2: TinyVec<[i32; 4]> = tv.drain(1..).collect();
  /// assert_eq!(tv.as_slice(), &[1][..]);
  /// assert_eq!(tv2.as_slice(), &[2, 3][..]);
  ///
  /// tv.drain(..);
  /// assert_eq!(tv.as_slice(), &[]);
  /// ```
  #[inline]
  pub fn drain<R: RangeBounds<usize>>(
    &mut self, range: R,
  ) -> TinyVecDrain<'_, A> {
    match self {
      TinyVec::Inline(i) => TinyVecDrain::Inline(i.drain(range)),
      TinyVec::Heap(h) => TinyVecDrain::Heap(h.drain(range)),
    }
  }

  /// Clone each element of the slice into this vec.
  /// ```rust
  /// use tinyvec::*;
  /// let mut tv = tiny_vec!([i32; 4] => 1, 2);
  /// tv.extend_from_slice(&[3, 4]);
  /// assert_eq!(tv.as_slice(), [1, 2, 3, 4]);
  /// ```
  #[inline]
  pub fn extend_from_slice(&mut self, sli: &[A::Item])
  where
    A::Item: Clone,
  {
    self.reserve(sli.len());
    match self {
      TinyVec::Inline(a) => a.extend_from_slice(sli),
      TinyVec::Heap(h) => h.extend_from_slice(sli),
    }
  }

  /// Wraps up an array and uses the given length as the initial length.
  ///
  /// Note that the `From` impl for arrays assumes the full length is used.
  ///
  /// ## Panics
  ///
  /// The length must be less than or equal to the capacity of the array.
  #[inline]
  #[must_use]
  #[allow(clippy::match_wild_err_arm)]
  pub fn from_array_len(data: A, len: usize) -> Self {
    match Self::try_from_array_len(data, len) {
      Ok(out) => out,
      Err(_) => {
        panic!("TinyVec: length {} exceeds capacity {}!", len, A::CAPACITY)
      }
    }
  }

  /// This is an internal implementation detail of the `tiny_vec!` macro, and
  /// using it other than from that macro is not supported by this crate's
  /// SemVer guarantee.
  #[inline(always)]
  #[doc(hidden)]
  pub fn constructor_for_capacity(cap: usize) -> TinyVecConstructor<A> {
    if cap <= A::CAPACITY {
      TinyVecConstructor::Inline(TinyVec::Inline)
    } else {
      TinyVecConstructor::Heap(TinyVec::Heap)
    }
  }

  /// Inserts an item at the position given, moving all following elements +1
  /// index.
  ///
  /// ## Panics
  /// * If `index` > `len`
  ///
  /// ## Example
  /// ```rust
  /// use tinyvec::*;
  /// let mut tv = tiny_vec!([i32; 10] => 1, 2, 3);
  /// tv.insert(1, 4);
  /// assert_eq!(tv.as_slice(), &[1, 4, 2, 3]);
  /// tv.insert(4, 5);
  /// assert_eq!(tv.as_slice(), &[1, 4, 2, 3, 5]);
  /// ```
  #[inline]
  pub fn insert(&mut self, index: usize, item: A::Item) {
    assert!(
      index <= self.len(),
      "insertion index (is {}) should be <= len (is {})",
      index,
      self.len()
    );

    let arr = match self {
      TinyVec::Heap(v) => return v.insert(index, item),
      TinyVec::Inline(a) => a,
    };

    if let Some(x) = arr.try_insert(index, item) {
      let mut v = Vec::with_capacity(arr.len() * 2);
      let mut it =
        arr.iter_mut().map(|r| core::mem::replace(r, Default::default()));
      v.extend(it.by_ref().take(index));
      v.push(x);
      v.extend(it);
      *self = TinyVec::Heap(v);
    }
  }

  /// If the vec is empty.
  #[inline(always)]
  #[must_use]
  pub fn is_empty(&self) -> bool {
    self.len() == 0
  }

  /// Makes a new, empty vec.
  #[inline(always)]
  #[must_use]
  pub fn new() -> Self {
    Self::default()
  }

  /// Place an element onto the end of the vec.
  /// ## Panics
  /// * If the length of the vec would overflow the capacity.
  /// ```rust
  /// use tinyvec::*;
  /// let mut tv = tiny_vec!([i32; 10] => 1, 2, 3);
  /// tv.push(4);
  /// assert_eq!(tv.as_slice(), &[1, 2, 3, 4]);
  /// ```
  #[inline]
  pub fn push(&mut self, val: A::Item) {
    // The code path for moving the inline contents to the heap produces a lot
    // of instructions, but we have a strong guarantee that this is a cold
    // path. LLVM doesn't know this, inlines it, and this tends to cause a
    // cascade of other bad inlining decisions because the body of push looks
    // huge even though nearly every call executes the same few instructions.
    //
    // Moving the logic out of line with #[cold] causes the hot code to  be
    // inlined together, and we take the extra cost of a function call only
    // in rare cases.
    #[cold]
    fn drain_to_heap_and_push<A: Array>(
      arr: &mut ArrayVec<A>, val: A::Item,
    ) -> TinyVec<A> {
      /* Make the Vec twice the size to amortize the cost of draining */
      let mut v = arr.drain_to_vec_and_reserve(arr.len());
      v.push(val);
      TinyVec::Heap(v)
    }

    match self {
      TinyVec::Heap(v) => v.push(val),
      TinyVec::Inline(arr) => {
        if let Some(x) = arr.try_push(val) {
          *self = drain_to_heap_and_push(arr, x);
        }
      }
    }
  }

  /// Resize the vec to the new length.
  ///
  /// If it needs to be longer, it's filled with clones of the provided value.
  /// If it needs to be shorter, it's truncated.
  ///
  /// ## Example
  ///
  /// ```rust
  /// use tinyvec::*;
  ///
  /// let mut tv = tiny_vec!([&str; 10] => "hello");
  /// tv.resize(3, "world");
  /// assert_eq!(tv.as_slice(), &["hello", "world", "world"][..]);
  ///
  /// let mut tv = tiny_vec!([i32; 10] => 1, 2, 3, 4);
  /// tv.resize(2, 0);
  /// assert_eq!(tv.as_slice(), &[1, 2][..]);
  /// ```
  #[inline]
  pub fn resize(&mut self, new_len: usize, new_val: A::Item)
  where
    A::Item: Clone,
  {
    self.resize_with(new_len, || new_val.clone());
  }

  /// Resize the vec to the new length.
  ///
  /// If it needs to be longer, it's filled with repeated calls to the provided
  /// function. If it needs to be shorter, it's truncated.
  ///
  /// ## Example
  ///
  /// ```rust
  /// use tinyvec::*;
  ///
  /// let mut tv = tiny_vec!([i32; 3] => 1, 2, 3);
  /// tv.resize_with(5, Default::default);
  /// assert_eq!(tv.as_slice(), &[1, 2, 3, 0, 0][..]);
  ///
  /// let mut tv = tiny_vec!([i32; 2]);
  /// let mut p = 1;
  /// tv.resize_with(4, || {
  ///   p *= 2;
  ///   p
  /// });
  /// assert_eq!(tv.as_slice(), &[2, 4, 8, 16][..]);
  /// ```
  #[inline]
  pub fn resize_with<F: FnMut() -> A::Item>(&mut self, new_len: usize, f: F) {
    match new_len.checked_sub(self.len()) {
      None => return self.truncate(new_len),
      Some(n) => self.reserve(n),
    }

    match self {
      TinyVec::Inline(a) => a.resize_with(new_len, f),
      TinyVec::Heap(v) => v.resize_with(new_len, f),
    }
  }

  /// Splits the collection at the point given.
  ///
  /// * `[0, at)` stays in this vec
  /// * `[at, len)` ends up in the new vec.
  ///
  /// ## Panics
  /// * if at > len
  ///
  /// ## Example
  ///
  /// ```rust
  /// use tinyvec::*;
  /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3);
  /// let tv2 = tv.split_off(1);
  /// assert_eq!(tv.as_slice(), &[1][..]);
  /// assert_eq!(tv2.as_slice(), &[2, 3][..]);
  /// ```
  #[inline]
  pub fn split_off(&mut self, at: usize) -> Self {
    match self {
      TinyVec::Inline(a) => TinyVec::Inline(a.split_off(at)),
      TinyVec::Heap(v) => TinyVec::Heap(v.split_off(at)),
    }
  }

  /// Creates a splicing iterator that removes the specified range in the
  /// vector, yields the removed items, and replaces them with elements from
  /// the provided iterator.
  ///
  /// `splice` fuses the provided iterator, so elements after the first `None`
  /// are ignored.
  ///
  /// ## Panics
  /// * If the start is greater than the end.
  /// * If the end is past the edge of the vec.
  /// * If the provided iterator panics.
  ///
  /// ## Example
  /// ```rust
  /// use tinyvec::*;
  /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3);
  /// let tv2: TinyVec<[i32; 4]> = tv.splice(1.., 4..=6).collect();
  /// assert_eq!(tv.as_slice(), &[1, 4, 5, 6][..]);
  /// assert_eq!(tv2.as_slice(), &[2, 3][..]);
  ///
  /// tv.splice(.., None);
  /// assert_eq!(tv.as_slice(), &[]);
  /// ```
  #[inline]
  pub fn splice<R, I>(
    &mut self, range: R, replacement: I,
  ) -> TinyVecSplice<'_, A, core::iter::Fuse<I::IntoIter>>
  where
    R: RangeBounds<usize>,
    I: IntoIterator<Item = A::Item>,
  {
    use core::ops::Bound;
    let start = match range.start_bound() {
      Bound::Included(x) => *x,
      Bound::Excluded(x) => x.saturating_add(1),
      Bound::Unbounded => 0,
    };
    let end = match range.end_bound() {
      Bound::Included(x) => x.saturating_add(1),
      Bound::Excluded(x) => *x,
      Bound::Unbounded => self.len(),
    };
    assert!(
      start <= end,
      "TinyVec::splice> Illegal range, {} to {}",
      start,
      end
    );
    assert!(
      end <= self.len(),
      "TinyVec::splice> Range ends at {} but length is only {}!",
      end,
      self.len()
    );

    TinyVecSplice {
      removal_start: start,
      removal_end: end,
      parent: self,
      replacement: replacement.into_iter().fuse(),
    }
  }

  /// Wraps an array, using the given length as the starting length.
  ///
  /// If you want to use the whole length of the array, you can just use the
  /// `From` impl.
  ///
  /// ## Failure
  ///
  /// If the given length is greater than the capacity of the array this will
  /// error, and you'll get the array back in the `Err`.
  #[inline]
  pub fn try_from_array_len(data: A, len: usize) -> Result<Self, A> {
    let arr = ArrayVec::try_from_array_len(data, len)?;
    Ok(TinyVec::Inline(arr))
  }
}

/// Draining iterator for `TinyVecDrain`
///
/// See [`TinyVecDrain::drain`](TinyVecDrain::<A>::drain)
#[cfg_attr(docs_rs, doc(cfg(feature = "alloc")))]
pub enum TinyVecDrain<'p, A: Array> {
  #[allow(missing_docs)]
  Inline(ArrayVecDrain<'p, A::Item>),
  #[allow(missing_docs)]
  Heap(vec::Drain<'p, A::Item>),
}

impl<'p, A: Array> Iterator for TinyVecDrain<'p, A> {
  type Item = A::Item;

  impl_mirrored! {
    type Mirror = TinyVecDrain;

    #[inline]
    fn next(self: &mut Self) -> Option<Self::Item>;
    #[inline]
    fn nth(self: &mut Self, n: usize) -> Option<Self::Item>;
    #[inline]
    fn size_hint(self: &Self) -> (usize, Option<usize>);
    #[inline]
    fn last(self: Self) -> Option<Self::Item>;
    #[inline]
    fn count(self: Self) -> usize;
  }

  #[inline]
  fn for_each<F: FnMut(Self::Item)>(self, f: F) {
    match self {
      TinyVecDrain::Inline(i) => i.for_each(f),
      TinyVecDrain::Heap(h) => h.for_each(f),
    }
  }
}

impl<'p, A: Array> DoubleEndedIterator for TinyVecDrain<'p, A> {
  impl_mirrored! {
    type Mirror = TinyVecDrain;

    #[inline]
    fn next_back(self: &mut Self) -> Option<Self::Item>;

    #[cfg(feature = "rustc_1_40")]
    #[inline]
    fn nth_back(self: &mut Self, n: usize) -> Option<Self::Item>;
  }
}

/// Splicing iterator for `TinyVec`
/// See [`TinyVec::splice`](TinyVec::<A>::splice)
#[cfg_attr(docs_rs, doc(cfg(feature = "alloc")))]
pub struct TinyVecSplice<'p, A: Array, I: Iterator<Item = A::Item>> {
  parent: &'p mut TinyVec<A>,
  removal_start: usize,
  removal_end: usize,
  replacement: I,
}

impl<'p, A, I> Iterator for TinyVecSplice<'p, A, I>
where
  A: Array,
  I: Iterator<Item = A::Item>,
{
  type Item = A::Item;

  #[inline]
  fn next(&mut self) -> Option<A::Item> {
    if self.removal_start < self.removal_end {
      match self.replacement.next() {
        Some(replacement) => {
          let removed = core::mem::replace(
            &mut self.parent[self.removal_start],
            replacement,
          );
          self.removal_start += 1;
          Some(removed)
        }
        None => {
          let removed = self.parent.remove(self.removal_start);
          self.removal_end -= 1;
          Some(removed)
        }
      }
    } else {
      None
    }
  }

  #[inline]
  fn size_hint(&self) -> (usize, Option<usize>) {
    let len = self.len();
    (len, Some(len))
  }
}

impl<'p, A, I> ExactSizeIterator for TinyVecSplice<'p, A, I>
where
  A: Array,
  I: Iterator<Item = A::Item>,
{
  #[inline]
  fn len(&self) -> usize {
    self.removal_end - self.removal_start
  }
}

impl<'p, A, I> FusedIterator for TinyVecSplice<'p, A, I>
where
  A: Array,
  I: Iterator<Item = A::Item>,
{
}

impl<'p, A, I> DoubleEndedIterator for TinyVecSplice<'p, A, I>
where
  A: Array,
  I: Iterator<Item = A::Item> + DoubleEndedIterator,
{
  #[inline]
  fn next_back(&mut self) -> Option<A::Item> {
    if self.removal_start < self.removal_end {
      match self.replacement.next_back() {
        Some(replacement) => {
          let removed = core::mem::replace(
            &mut self.parent[self.removal_end - 1],
            replacement,
          );
          self.removal_end -= 1;
          Some(removed)
        }
        None => {
          let removed = self.parent.remove(self.removal_end - 1);
          self.removal_end -= 1;
          Some(removed)
        }
      }
    } else {
      None
    }
  }
}

impl<'p, A: Array, I: Iterator<Item = A::Item>> Drop
  for TinyVecSplice<'p, A, I>
{
  fn drop(&mut self) {
    for _ in self.by_ref() {}

    let (lower_bound, _) = self.replacement.size_hint();
    self.parent.reserve(lower_bound);

    for replacement in self.replacement.by_ref() {
      self.parent.insert(self.removal_end, replacement);
      self.removal_end += 1;
    }
  }
}

impl<A: Array> AsMut<[A::Item]> for TinyVec<A> {
  #[inline(always)]
  #[must_use]
  fn as_mut(&mut self) -> &mut [A::Item] {
    &mut *self
  }
}

impl<A: Array> AsRef<[A::Item]> for TinyVec<A> {
  #[inline(always)]
  #[must_use]
  fn as_ref(&self) -> &[A::Item] {
    &*self
  }
}

impl<A: Array> Borrow<[A::Item]> for TinyVec<A> {
  #[inline(always)]
  #[must_use]
  fn borrow(&self) -> &[A::Item] {
    &*self
  }
}

impl<A: Array> BorrowMut<[A::Item]> for TinyVec<A> {
  #[inline(always)]
  #[must_use]
  fn borrow_mut(&mut self) -> &mut [A::Item] {
    &mut *self
  }
}

impl<A: Array> Extend<A::Item> for TinyVec<A> {
  #[inline]
  fn extend<T: IntoIterator<Item = A::Item>>(&mut self, iter: T) {
    let iter = iter.into_iter();
    let (lower_bound, _) = iter.size_hint();
    self.reserve(lower_bound);

    let a = match self {
      TinyVec::Heap(h) => return h.extend(iter),
      TinyVec::Inline(a) => a,
    };

    let mut iter = a.fill(iter);
    let maybe = iter.next();

    let surely = match maybe {
      Some(x) => x,
      None => return,
    };

    let mut v = a.drain_to_vec_and_reserve(a.len());
    v.push(surely);
    v.extend(iter);
    *self = TinyVec::Heap(v);
  }
}

impl<A: Array> From<ArrayVec<A>> for TinyVec<A> {
  #[inline(always)]
  #[must_use]
  fn from(arr: ArrayVec<A>) -> Self {
    TinyVec::Inline(arr)
  }
}

impl<A: Array> From<A> for TinyVec<A> {
  fn from(array: A) -> Self {
    TinyVec::Inline(ArrayVec::from(array))
  }
}

impl<T, A> From<&'_ [T]> for TinyVec<A>
where
  T: Clone + Default,
  A: Array<Item = T>,
{
  #[inline]
  #[must_use]
  fn from(slice: &[T]) -> Self {
    if slice.len() > A::CAPACITY {
      TinyVec::Heap(slice.into())
    } else {
      let mut arr = ArrayVec::new();
      // We do not use ArrayVec::extend_from_slice, because it looks like LLVM
      // fails to deduplicate all the length-checking logic between the
      // above if and the contents of that method, thus producing much
      // slower code. Unlike many of the other optimizations in this
      // crate, this one is worth keeping an eye on. I see no reason, for
      // any element type, that these should produce different code. But
      // they do. (rustc 1.51.0)
      arr.set_len(slice.len());
      arr.as_mut_slice().clone_from_slice(slice);
      TinyVec::Inline(arr)
    }
  }
}

impl<T, A> From<&'_ mut [T]> for TinyVec<A>
where
  T: Clone + Default,
  A: Array<Item = T>,
{
  #[inline]
  #[must_use]
  fn from(slice: &mut [T]) -> Self {
    Self::from(&*slice)
  }
}

impl<A: Array> FromIterator<A::Item> for TinyVec<A> {
  #[inline]
  #[must_use]
  fn from_iter<T: IntoIterator<Item = A::Item>>(iter: T) -> Self {
    let mut av = Self::default();
    av.extend(iter);
    av
  }
}

/// Iterator for consuming an `TinyVec` and returning owned elements.
#[cfg_attr(docs_rs, doc(cfg(feature = "alloc")))]
pub enum TinyVecIterator<A: Array> {
  #[allow(missing_docs)]
  Inline(ArrayVecIterator<A>),
  #[allow(missing_docs)]
  Heap(alloc::vec::IntoIter<A::Item>),
}

impl<A: Array> TinyVecIterator<A> {
  impl_mirrored! {
    type Mirror = TinyVecIterator;
    /// Returns the remaining items of this iterator as a slice.
    #[inline]
    #[must_use]
    pub fn as_slice(self: &Self) -> &[A::Item];
  }
}

impl<A: Array> FusedIterator for TinyVecIterator<A> {}

impl<A: Array> Iterator for TinyVecIterator<A> {
  type Item = A::Item;

  impl_mirrored! {
    type Mirror = TinyVecIterator;

    #[inline]
    fn next(self: &mut Self) -> Option<Self::Item>;

    #[inline(always)]
    #[must_use]
    fn size_hint(self: &Self) -> (usize, Option<usize>);

    #[inline(always)]
    fn count(self: Self) -> usize;

    #[inline]
    fn last(self: Self) -> Option<Self::Item>;

    #[inline]
    fn nth(self: &mut Self, n: usize) -> Option<A::Item>;
  }
}

impl<A: Array> Debug for TinyVecIterator<A>
where
  A::Item: Debug,
{
  #[allow(clippy::missing_inline_in_public_items)]
  fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
    f.debug_tuple("TinyVecIterator").field(&self.as_slice()).finish()
  }
}

impl<A: Array> IntoIterator for TinyVec<A> {
  type Item = A::Item;
  type IntoIter = TinyVecIterator<A>;
  #[inline(always)]
  #[must_use]
  fn into_iter(self) -> Self::IntoIter {
    match self {
      TinyVec::Inline(a) => TinyVecIterator::Inline(a.into_iter()),
      TinyVec::Heap(v) => TinyVecIterator::Heap(v.into_iter()),
    }
  }
}

impl<'a, A: Array> IntoIterator for &'a mut TinyVec<A> {
  type Item = &'a mut A::Item;
  type IntoIter = core::slice::IterMut<'a, A::Item>;
  #[inline(always)]
  #[must_use]
  fn into_iter(self) -> Self::IntoIter {
    self.iter_mut()
  }
}

impl<'a, A: Array> IntoIterator for &'a TinyVec<A> {
  type Item = &'a A::Item;
  type IntoIter = core::slice::Iter<'a, A::Item>;
  #[inline(always)]
  #[must_use]
  fn into_iter(self) -> Self::IntoIter {
    self.iter()
  }
}

impl<A: Array> PartialEq for TinyVec<A>
where
  A::Item: PartialEq,
{
  #[inline]
  #[must_use]
  fn eq(&self, other: &Self) -> bool {
    self.as_slice().eq(other.as_slice())
  }
}
impl<A: Array> Eq for TinyVec<A> where A::Item: Eq {}

impl<A: Array> PartialOrd for TinyVec<A>
where
  A::Item: PartialOrd,
{
  #[inline]
  #[must_use]
  fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
    self.as_slice().partial_cmp(other.as_slice())
  }
}
impl<A: Array> Ord for TinyVec<A>
where
  A::Item: Ord,
{
  #[inline]
  #[must_use]
  fn cmp(&self, other: &Self) -> core::cmp::Ordering {
    self.as_slice().cmp(other.as_slice())
  }
}

impl<A: Array> PartialEq<&A> for TinyVec<A>
where
  A::Item: PartialEq,
{
  #[inline]
  #[must_use]
  fn eq(&self, other: &&A) -> bool {
    self.as_slice().eq(other.as_slice())
  }
}

impl<A: Array> PartialEq<&[A::Item]> for TinyVec<A>
where
  A::Item: PartialEq,
{
  #[inline]
  #[must_use]
  fn eq(&self, other: &&[A::Item]) -> bool {
    self.as_slice().eq(*other)
  }
}

impl<A: Array> Hash for TinyVec<A>
where
  A::Item: Hash,
{
  #[inline]
  fn hash<H: Hasher>(&self, state: &mut H) {
    self.as_slice().hash(state)
  }
}

// // // // // // // //
// Formatting impls
// // // // // // // //

impl<A: Array> Binary for TinyVec<A>
where
  A::Item: Binary,
{
  #[allow(clippy::missing_inline_in_public_items)]
  fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
    write!(f, "[")?;
    for (i, elem) in self.iter().enumerate() {
      if i > 0 {
        write!(f, ", ")?;
      }
      Binary::fmt(elem, f)?;
    }
    write!(f, "]")
  }
}

impl<A: Array> Debug for TinyVec<A>
where
  A::Item: Debug,
{
  #[allow(clippy::missing_inline_in_public_items)]
  fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
    write!(f, "[")?;
    for (i, elem) in self.iter().enumerate() {
      if i > 0 {
        write!(f, ", ")?;
      }
      Debug::fmt(elem, f)?;
    }
    write!(f, "]")
  }
}

impl<A: Array> Display for TinyVec<A>
where
  A::Item: Display,
{
  #[allow(clippy::missing_inline_in_public_items)]
  fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
    write!(f, "[")?;
    for (i, elem) in self.iter().enumerate() {
      if i > 0 {
        write!(f, ", ")?;
      }
      Display::fmt(elem, f)?;
    }
    write!(f, "]")
  }
}

impl<A: Array> LowerExp for TinyVec<A>
where
  A::Item: LowerExp,
{
  #[allow(clippy::missing_inline_in_public_items)]
  fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
    write!(f, "[")?;
    for (i, elem) in self.iter().enumerate() {
      if i > 0 {
        write!(f, ", ")?;
      }
      LowerExp::fmt(elem, f)?;
    }
    write!(f, "]")
  }
}

impl<A: Array> LowerHex for TinyVec<A>
where
  A::Item: LowerHex,
{
  #[allow(clippy::missing_inline_in_public_items)]
  fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
    write!(f, "[")?;
    for (i, elem) in self.iter().enumerate() {
      if i > 0 {
        write!(f, ", ")?;
      }
      LowerHex::fmt(elem, f)?;
    }
    write!(f, "]")
  }
}

impl<A: Array> Octal for TinyVec<A>
where
  A::Item: Octal,
{
  #[allow(clippy::missing_inline_in_public_items)]
  fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
    write!(f, "[")?;
    for (i, elem) in self.iter().enumerate() {
      if i > 0 {
        write!(f, ", ")?;
      }
      Octal::fmt(elem, f)?;
    }
    write!(f, "]")
  }
}

impl<A: Array> Pointer for TinyVec<A>
where
  A::Item: Pointer,
{
  #[allow(clippy::missing_inline_in_public_items)]
  fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
    write!(f, "[")?;
    for (i, elem) in self.iter().enumerate() {
      if i > 0 {
        write!(f, ", ")?;
      }
      Pointer::fmt(elem, f)?;
    }
    write!(f, "]")
  }
}

impl<A: Array> UpperExp for TinyVec<A>
where
  A::Item: UpperExp,
{
  #[allow(clippy::missing_inline_in_public_items)]
  fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
    write!(f, "[")?;
    for (i, elem) in self.iter().enumerate() {
      if i > 0 {
        write!(f, ", ")?;
      }
      UpperExp::fmt(elem, f)?;
    }
    write!(f, "]")
  }
}

impl<A: Array> UpperHex for TinyVec<A>
where
  A::Item: UpperHex,
{
  #[allow(clippy::missing_inline_in_public_items)]
  fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
    write!(f, "[")?;
    for (i, elem) in self.iter().enumerate() {
      if i > 0 {
        write!(f, ", ")?;
      }
      UpperHex::fmt(elem, f)?;
    }
    write!(f, "]")
  }
}

#[cfg(feature = "serde")]
#[cfg_attr(docs_rs, doc(cfg(feature = "alloc")))]
struct TinyVecVisitor<A: Array>(PhantomData<A>);

#[cfg(feature = "serde")]
impl<'de, A: Array> Visitor<'de> for TinyVecVisitor<A>
where
  A::Item: Deserialize<'de>,
{
  type Value = TinyVec<A>;

  fn expecting(
    &self, formatter: &mut core::fmt::Formatter,
  ) -> core::fmt::Result {
    formatter.write_str("a sequence")
  }

  fn visit_seq<S>(self, mut seq: S) -> Result<Self::Value, S::Error>
  where
    S: SeqAccess<'de>,
  {
    let mut new_tinyvec = match seq.size_hint() {
      Some(expected_size) => TinyVec::with_capacity(expected_size),
      None => Default::default(),
    };

    while let Some(value) = seq.next_element()? {
      new_tinyvec.push(value);
    }

    Ok(new_tinyvec)
  }
}
