#![cfg(feature = "alloc")]

use super::*;

use alloc::vec::{self, Vec};
use core::convert::TryFrom;
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);
/// ```
#[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> Clone for TinyVec<A>
where
  A: Array + Clone,
  A::Item: Clone,
{
  #[inline]
  fn clone(&self) -> Self {
    match self {
      Self::Heap(v) => Self::Heap(v.clone()),
      Self::Inline(v) => Self::Inline(v.clone()),
    }
  }

  #[inline]
  fn clone_from(&mut self, o: &Self) {
    if o.len() > self.len() {
      self.reserve(o.len() - self.len());
    } else {
      self.truncate(o.len());
    }
    let (start, end) = o.split_at(self.len());
    for (dst, src) in self.iter_mut().zip(start) {
      dst.clone_from(src);
    }
    self.extend_from_slice(end);
  }
}

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))
  }
}

#[cfg(feature = "arbitrary")]
#[cfg_attr(docs_rs, doc(cfg(feature = "arbitrary")))]
impl<'a, A> arbitrary::Arbitrary<'a> for TinyVec<A>
where
  A: Array,
  A::Item: arbitrary::Arbitrary<'a>,
{
  fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
    let v = Vec::arbitrary(u)?;
    let mut tv = TinyVec::Heap(v);
    tv.shrink_to_fit();
    Ok(tv)
  }
}

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 let Ok(arr) = ArrayVec::try_from(slice) {
      TinyVec::Inline(arr)
    } else {
      TinyVec::Heap(slice.into())
    }
  }
}

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> DoubleEndedIterator for TinyVecIterator<A> {
  impl_mirrored! {
    type Mirror = TinyVecIterator;

    #[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>;
  }
}

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, "[")?;
    if f.alternate() {
      write!(f, "\n    ")?;
    }
    for (i, elem) in self.iter().enumerate() {
      if i > 0 {
        write!(f, ",{}", if f.alternate() { "\n    " } else { " " })?;
      }
      Binary::fmt(elem, f)?;
    }
    if f.alternate() {
      write!(f, ",\n")?;
    }
    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, "[")?;
    if f.alternate() {
      write!(f, "\n    ")?;
    }
    for (i, elem) in self.iter().enumerate() {
      if i > 0 {
        write!(f, ",{}", if f.alternate() { "\n    " } else { " " })?;
      }
      Debug::fmt(elem, f)?;
    }
    if f.alternate() {
      write!(f, ",\n")?;
    }
    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, "[")?;
    if f.alternate() {
      write!(f, "\n    ")?;
    }
    for (i, elem) in self.iter().enumerate() {
      if i > 0 {
        write!(f, ",{}", if f.alternate() { "\n    " } else { " " })?;
      }
      Display::fmt(elem, f)?;
    }
    if f.alternate() {
      write!(f, ",\n")?;
    }
    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, "[")?;
    if f.alternate() {
      write!(f, "\n    ")?;
    }
    for (i, elem) in self.iter().enumerate() {
      if i > 0 {
        write!(f, ",{}", if f.alternate() { "\n    " } else { " " })?;
      }
      LowerExp::fmt(elem, f)?;
    }
    if f.alternate() {
      write!(f, ",\n")?;
    }
    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, "[")?;
    if f.alternate() {
      write!(f, "\n    ")?;
    }
    for (i, elem) in self.iter().enumerate() {
      if i > 0 {
        write!(f, ",{}", if f.alternate() { "\n    " } else { " " })?;
      }
      LowerHex::fmt(elem, f)?;
    }
    if f.alternate() {
      write!(f, ",\n")?;
    }
    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, "[")?;
    if f.alternate() {
      write!(f, "\n    ")?;
    }
    for (i, elem) in self.iter().enumerate() {
      if i > 0 {
        write!(f, ",{}", if f.alternate() { "\n    " } else { " " })?;
      }
      Octal::fmt(elem, f)?;
    }
    if f.alternate() {
      write!(f, ",\n")?;
    }
    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, "[")?;
    if f.alternate() {
      write!(f, "\n    ")?;
    }
    for (i, elem) in self.iter().enumerate() {
      if i > 0 {
        write!(f, ",{}", if f.alternate() { "\n    " } else { " " })?;
      }
      Pointer::fmt(elem, f)?;
    }
    if f.alternate() {
      write!(f, ",\n")?;
    }
    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, "[")?;
    if f.alternate() {
      write!(f, "\n    ")?;
    }
    for (i, elem) in self.iter().enumerate() {
      if i > 0 {
        write!(f, ",{}", if f.alternate() { "\n    " } else { " " })?;
      }
      UpperExp::fmt(elem, f)?;
    }
    if f.alternate() {
      write!(f, ",\n")?;
    }
    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, "[")?;
    if f.alternate() {
      write!(f, "\n    ")?;
    }
    for (i, elem) in self.iter().enumerate() {
      if i > 0 {
        write!(f, ",{}", if f.alternate() { "\n    " } else { " " })?;
      }
      UpperHex::fmt(elem, f)?;
    }
    if f.alternate() {
      write!(f, ",\n")?;
    }
    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)
  }
}
