// Part of the Crubit project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
extern crate alloc;
use alloc::borrow::Borrow;
use alloc::borrow::BorrowMut;
use core::cmp::Ordering;

use alloc::collections::TryReserveError;
use alloc::vec::Vec;
#[cfg(sanitize = "address")]
use core::ffi::c_void;
use core::fmt::Debug;
use core::hash::Hash;
use core::hash::Hasher;
use core::iter::FromIterator;
use core::mem::ManuallyDrop;
use core::ops::RangeBounds;
use core::ops::{Deref, DerefMut};
use core::ops::{Index, IndexMut};
use core::slice;
use core::slice::SliceIndex;

use crate::crubit_cc_std_internal::std_allocator as cpp_std_allocator;

extern "C" {
    // https://github.com/llvm/llvm-project/blob/9d0616ce52fc2a75c8e4808adec41d5189f4240c/compiler-rt/lib/sanitizer_common/sanitizer_interface_internal.h#L70
    #[cfg(sanitize = "address")]
    fn __sanitizer_annotate_contiguous_container(
        beg: *const c_void,
        end: *const c_void,
        old_mid: *const c_void,
        new_mid: *const c_void,
    );
}

/// A mutable, contiguous, dynamically-sized container of elements
/// of type `T`, ABI-compatible with `std::vector` from C++.
/// 2 layouts are supported.
/// 1. This layout was found empirically on Linux with modern g++ and libc++. If
/// for some version of libc++ it is different, we will need to update it with
/// conditional compilation.
#[cfg(not(feature = "len_capacity_encoding"))]
#[repr(C)]
pub struct vector<T> {
    // Note: the pointers are mutable, but `const` for covariance.
    begin: *const T,
    _end: *const T,
    _capacity_end: *const T,
}

/// 2. This layout is experimental.
#[cfg(feature = "len_capacity_encoding")]
#[repr(C)]
pub struct vector<T> {
    /// The pointer to the first element of the vector.
    ///
    /// This pointer is mutable, but `const` for covariance.
    begin: *const T,
    len: usize,
    capacity: usize,
}

impl<T> vector<T> {
    pub fn new() -> vector<T> {
        #[cfg(feature = "len_capacity_encoding")]
        {
            vector { begin: core::ptr::null_mut(), len: 0, capacity: 0 }
        }
        #[cfg(not(feature = "len_capacity_encoding"))]
        {
            vector {
                begin: core::ptr::null_mut(),
                _end: core::ptr::null_mut(),
                _capacity_end: core::ptr::null_mut(),
            }
        }
    }

    pub fn len(&self) -> usize {
        #[cfg(feature = "len_capacity_encoding")]
        {
            self.len
        }
        #[cfg(not(feature = "len_capacity_encoding"))]
        {
            use core::convert::TryInto;
            // SAFETY:
            // 1: self.begin - self._end are either both null (for the empty vector),
            //    or point to the beginning and ending of the vector inside the allocation
            //    for the vector.
            // 2: The vector is aligned for `T`.
            unsafe { self._end.offset_from(self.begin).try_into().unwrap() }
        }
    }

    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }

    pub fn capacity(&self) -> usize {
        #[cfg(feature = "len_capacity_encoding")]
        {
            self.capacity
        }
        #[cfg(not(feature = "len_capacity_encoding"))]
        {
            use core::convert::TryInto;
            // SAFETY:
            // 1: self.begin - self._capacity_end are either both null (for the empty vector),
            //    or point to the beginning and ending of the whole allocation for the vector.
            // 2: The vector is aligned for `T`.
            unsafe { self._capacity_end.offset_from(self.begin).try_into().unwrap() }
        }
    }

    fn end(&self) -> *mut T {
        #[cfg(feature = "len_capacity_encoding")]
        {
            unsafe { self.begin.add(self.len) as *mut _ }
        }
        #[cfg(not(feature = "len_capacity_encoding"))]
        {
            self._end as *mut _
        }
    }

    fn capacity_end(&self) -> *mut T {
        #[cfg(feature = "len_capacity_encoding")]
        {
            unsafe { self.begin.add(self.capacity) as *mut _ }
        }
        #[cfg(not(feature = "len_capacity_encoding"))]
        {
            self._capacity_end as *mut _
        }
    }

    /// Sets the begin, len and capacity of the vector.
    ///
    /// This function overrides the pointer `self.begin` w/o deleting the
    /// pointed memory. That is the responsibility of the caller to ensure that
    /// no leaks occur.
    ///
    /// # Safety
    ///
    /// - `begin` must be a null and (len == capacity == 0) or  `begin` must be
    ///   a valid pointer and the memory pointed by `begin` must be allocated
    ///   with `StdAllocator`.
    /// - `len` must be less than or equal to `capacity`.
    /// - The first `len` values must be properly initialized values of type
    ///   `T`.
    /// - The size of `T `times the `capacity` (i.e. the allocated size in
    ///   bytes) needs to be the same size as the pointer was allocated with.
    /// - `T` needs to have the same alignment as what `begin` was allocated
    ///   with.
    /// - nothing else believes to have ownership over the memory of `begin`,
    ///   and that no outstanding references to this memory are still present by
    ///   the time `self` is next used.
    ///
    /// These requirements are always upheld by any `begin` that has been
    /// allocated via Vec<T, StdAllocator> and the corresponding Vec is
    /// forgotten after the call of this function. It follows by the properties
    /// of the `Vec`.
    unsafe fn set_begin_len_capacity(&mut self, begin: *mut T, len: usize, capacity: usize) {
        #[cfg(feature = "len_capacity_encoding")]
        {
            self.begin = begin as *const _;
            self.len = len;
            self.capacity = capacity;
        }
        #[cfg(not(feature = "len_capacity_encoding"))]
        {
            self.begin = begin as *const _;
            self._end = self.begin.add(len);
            self._capacity_end = self.begin.add(capacity);
        }
    }

    /// Prepares the vector to write into the tail.
    /// See docstring of [`vector::set_len`] for more details.
    pub fn prepare_to_write_into_tail(&mut self) {
        self.asan_unpoison_tail();
    }

    /// Sets the length of the vector.
    ///
    ///  # Safety
    ///
    /// - `new_len` must be less than or equal to [`capacity()`].
    /// - The elements at `old_len..new_len` must be initialized.
    ///
    /// See [`alloc::vec::Vec::set_len`] for more details.
    ///
    /// The difference with `alloc::vec::Vec::set_len` is that the tail of the
    /// vector is poisoned with ASan, so when writing to the tail for
    /// avoiding ASan errors [`vector::prepare_to_write_into_tail`] must be
    /// called first:
    /// ```
    /// v.prepare_to_write_into_tail()
    /// // write to tail (i.e. between v.len() and v.capacity())
    /// v.set_len(len)
    /// ```
    pub unsafe fn set_len(&mut self, len: usize) {
        #[cfg(feature = "len_capacity_encoding")]
        {
            self.len = len;
        }
        #[cfg(not(feature = "len_capacity_encoding"))]
        {
            self._end = self.begin.add(len);
        }
        self.asan_poison_tail();
    }

    #[inline]
    #[cfg(not(sanitize = "address"))]
    fn asan_poison_tail(&self) {}

    #[inline]
    #[cfg(not(sanitize = "address"))]
    fn asan_unpoison_tail(&self) {}

    #[inline]
    #[cfg(sanitize = "address")]
    fn asan_poison_tail(&self) {
        // C++ std::vector supports an ASan container annotation feature
        // (https://github.com/google/sanitizers/wiki/AddressSanitizerContainerOverflow)
        // that allows ASan to detect reads and writes in the uninitialized tail of the
        // std::vector's storage (between the end iterator and capacity).
        //
        // Rust alloc::vec::Vec intentionally does not support this ASan annotation
        // feature, because it allows users to initialize the elements in the
        // tail of the storage and then call set_len to tell the Vec about new
        // elements.
        //
        // ASan uses the term "poisoned" for data that cannot be accessed. When marking
        // data as inaccessible, we poison it, to make them accessible we
        // unpoison the data. So, the tail of a Rust Vec's storage is always
        // unpoisoned, even when ASan is enabled.
        //
        // Thus, when we use Rust Vec to implement operations on C++ std::vector's
        // storage, we hit an incompatibility: the tail of the C++ std::vector
        // is poisoned, but Rust Vec does not unpoison before writing into it.
        //
        // Therefore, when we create a Rust Vec using the storage of a C++ std::vector
        // we need to establish the ASan poision/unpoison invariants that the Rust Vec
        // expects. Specifically, we unpoison the storage before a Rust Vec
        // writes into the uninitialized tail. Furthermore, once we are done
        // using a Rust Vec to manipulate the storage, we poison the tail agail.
        //
        // As an optimization we don't poison/unpoison the tail when we create a Rust
        // Vec purely to perform reads, or to mutate existing elements in-place.
        unsafe {
            // The following call is the same as __annotate_new in C++ std::vector
            // https://github.com/llvm/llvm-project/blob/9d0616ce52fc2a75c8e4808adec41d5189f4240c/libcxx/include/vector#L920
            __sanitizer_annotate_contiguous_container(
                self.begin as *const c_void,
                self.capacity_end() as *const c_void,
                self.capacity_end() as *const c_void,
                self.end() as *const c_void,
            );
        }
    }

    #[inline]
    #[cfg(sanitize = "address")]
    fn asan_unpoison_tail(&self) {
        unsafe {
            // The following call is the same as __annotate_delete in C++
            // std::vector https://github.com/llvm/llvm-project/blob/9d0616ce52fc2a75c8e4808adec41d5189f4240c/libcxx/include/vector#L927
            __sanitizer_annotate_contiguous_container(
                self.begin as *const c_void,
                self.capacity_end() as *const c_void,
                self.end() as *const c_void,
                self.capacity_end() as *const c_void,
            );
        }
    }
}

impl<T: Unpin> vector<T> {
    /// Mutates `self` as if it were a `Vec<T>`.
    fn mutate_self_as_vec<F, R>(&mut self, mutate_self: F) -> R
    where
        F: FnOnce(&mut Vec<T, cpp_std_allocator::StdAllocator>) -> R,
    {
        unsafe {
            self.asan_unpoison_tail();
            let mut v = ManuallyDrop::new(create_vec_from_raw_parts(
                self.begin as *mut _,
                self.len(),
                self.capacity(),
            ));
            let result = mutate_self(v.deref_mut());
            self.set_begin_len_capacity(v.as_mut_ptr(), v.len(), v.capacity());
            self.asan_poison_tail();
            result
        }
    }

    // Methods for changing the capacity of the vector.
    pub fn reserve(&mut self, capacity: usize) {
        self.mutate_self_as_vec(|v| v.reserve(capacity));
    }

    pub fn reserve_exact(&mut self, additional: usize) {
        self.mutate_self_as_vec(|v| v.reserve_exact(additional));
    }

    pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
        self.mutate_self_as_vec(|v| v.try_reserve(additional))
    }

    pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> {
        self.mutate_self_as_vec(|v| v.try_reserve_exact(additional))
    }

    pub fn shrink_to_fit(&mut self) {
        self.mutate_self_as_vec(|v| v.shrink_to_fit());
    }

    pub fn shrink_to(&mut self, min_capacity: usize) {
        self.mutate_self_as_vec(|v| v.shrink_to(min_capacity));
    }

    pub fn with_capacity(capacity: usize) -> vector<T> {
        let mut result = vector::new();
        result.reserve(capacity);
        result
    }

    // Methods for adding elements to the vector.
    pub fn push(&mut self, value: T) {
        self.mutate_self_as_vec(|v| v.push(value));
    }

    pub fn insert(&mut self, index: usize, element: T) {
        self.mutate_self_as_vec(|v| v.insert(index, element));
    }

    pub fn append(&mut self, other: &mut Self) {
        self.mutate_self_as_vec(|v| other.mutate_self_as_vec(|other_v| v.append(other_v)))
    }

    // Methods for deleting elements from the vector.
    pub fn swap_remove(&mut self, index: usize) -> T {
        self.mutate_self_as_vec(|v| v.swap_remove(index))
    }

    pub fn remove(&mut self, index: usize) -> T {
        self.mutate_self_as_vec(|v| v.remove(index))
    }

    pub fn pop(&mut self) -> Option<T> {
        self.mutate_self_as_vec(|v| v.pop())
    }

    pub fn clear(&mut self) {
        self.mutate_self_as_vec(|v| v.clear());
    }

    pub fn truncate(&mut self, len: usize) {
        self.mutate_self_as_vec(|v| v.truncate(len));
    }

    // Different vector transformations.
    pub fn dedup_by<F>(&mut self, same_bucket: F)
    where
        F: FnMut(&mut T, &mut T) -> bool,
    {
        self.mutate_self_as_vec(|v| v.dedup_by(same_bucket));
    }

    pub fn dedup_by_key<F, K>(&mut self, key: F)
    where
        F: FnMut(&mut T) -> K,
        K: PartialEq,
    {
        self.mutate_self_as_vec(|v| v.dedup_by_key(key));
    }

    pub fn retain<F>(&mut self, f: F)
    where
        F: FnMut(&T) -> bool,
    {
        self.mutate_self_as_vec(|v| v.retain(f));
    }

    pub fn retain_mut<F>(&mut self, f: F)
    where
        F: FnMut(&mut T) -> bool,
    {
        self.mutate_self_as_vec(|v| v.retain_mut(f));
    }

    pub fn split_off(&mut self, at: usize) -> Self {
        vector::from(self.mutate_self_as_vec(|v| v.split_off(at)))
    }

    // Methods returning different vector representations.
    pub fn into_vec(mut self) -> Vec<T> {
        let mut result = Vec::<T>::with_capacity(self.len());
        unsafe {
            core::ptr::copy_nonoverlapping(self.as_ptr(), result.as_mut_ptr(), self.len());
            result.set_len(self.len());

            // The elements were moved out. Now mark `self` empty, without calling drop on
            // elements.
            self.asan_unpoison_tail();
            self.set_len(0);
        }
        result
    }

    pub fn as_ptr(&self) -> *const T {
        self.begin
    }

    pub fn as_mut_ptr(&mut self) -> *mut T {
        self.begin as *mut _
    }

    pub fn as_slice(&self) -> &[T] {
        unsafe {
            if self.begin.is_null() {
                &[]
            } else {
                core::slice::from_raw_parts(self.begin, self.len())
            }
        }
    }

    pub fn as_mut_slice(&mut self) -> &mut [T] {
        unsafe {
            if self.begin.is_null() {
                &mut []
            } else {
                core::slice::from_raw_parts_mut(self.begin as *mut _, self.len())
            }
        }
    }
}

impl<T: Unpin + Clone> vector<T> {
    pub fn extend_from_slice(&mut self, src: &[T]) {
        self.mutate_self_as_vec(|v| v.extend_from_slice(src));
    }

    pub fn extend_from_within<R>(&mut self, src: R)
    where
        R: RangeBounds<usize>,
    {
        self.mutate_self_as_vec(|v| v.extend_from_within(src));
    }

    pub fn resize(&mut self, new_len: usize, value: T) {
        self.mutate_self_as_vec(|v| v.resize(new_len, value));
    }

    pub fn resize_with<F>(&mut self, new_len: usize, f: F)
    where
        F: FnMut() -> T,
    {
        self.mutate_self_as_vec(|v| v.resize_with(new_len, f));
    }
}

impl<T: Unpin + PartialEq> vector<T> {
    pub fn dedup(&mut self) {
        self.mutate_self_as_vec(|v| v.dedup());
    }
}

impl<T> AsRef<vector<T>> for vector<T> {
    fn as_ref(&self) -> &vector<T> {
        self
    }
}

impl<T> AsMut<vector<T>> for vector<T> {
    fn as_mut(&mut self) -> &mut vector<T> {
        self
    }
}

impl<T: Unpin> AsRef<[T]> for vector<T> {
    fn as_ref(&self) -> &[T] {
        self.as_slice()
    }
}

impl<T: Unpin> AsMut<[T]> for vector<T> {
    fn as_mut(&mut self) -> &mut [T] {
        self.as_mut_slice()
    }
}

impl<T: Unpin> Borrow<[T]> for vector<T> {
    fn borrow(&self) -> &[T] {
        self.as_slice()
    }
}

impl<T: Unpin> BorrowMut<[T]> for vector<T> {
    fn borrow_mut(&mut self) -> &mut [T] {
        self.as_mut_slice()
    }
}

impl<T: Unpin + Debug> Debug for vector<T> {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        f.debug_list().entries(self.as_slice()).finish()
    }
}

impl<T> Default for vector<T> {
    fn default() -> Self {
        Self::new()
    }
}

impl<T> Drop for vector<T> {
    fn drop(&mut self) {
        if !self.begin.is_null() {
            unsafe {
                self.asan_unpoison_tail();
                _ = Vec::from_raw_parts_in(
                    self.begin as *mut T,
                    self.len(),
                    self.capacity(),
                    cpp_std_allocator::StdAllocator {},
                );
            }
        }
    }
}

impl<T: Unpin, I: SliceIndex<[T]>> Index<I> for vector<T> {
    type Output = I::Output;
    fn index(&self, index: I) -> &Self::Output {
        self.as_slice().index(index)
    }
}

impl<T: Unpin, I: SliceIndex<[T]>> IndexMut<I> for vector<T> {
    fn index_mut(&mut self, index: I) -> &mut Self::Output {
        self.as_mut_slice().index_mut(index)
    }
}

impl<T> Deref for vector<T> {
    type Target = [T];
    fn deref(&self) -> &Self::Target {
        if self.is_empty() {
            &[]
        } else {
            unsafe { core::slice::from_raw_parts(self.begin, self.len()) }
        }
    }
}

impl<T: Unpin> DerefMut for vector<T> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        if self.is_empty() {
            &mut []
        } else {
            unsafe { core::slice::from_raw_parts_mut(self.begin as *mut _, self.len()) }
        }
    }
}

impl<T: Clone> vector<T> {
    /// Clone elements from `self` to `Vec<T>`.
    pub fn to_vec(&self) -> Vec<T> {
        let mut v = Vec::<T>::with_capacity(self.len());
        for el in self.iter() {
            v.push(el.clone());
        }
        v
    }
}

impl<T: Unpin + Clone> Clone for vector<T> {
    fn clone(&self) -> Self {
        unsafe {
            let vec = ManuallyDrop::new(create_vec_from_raw_parts(
                self.begin as *mut _,
                self.len(),
                self.capacity(),
            ));
            vector::from((*vec).clone())
        }
    }
}

impl<T: Unpin> Extend<T> for vector<T> {
    fn extend<I>(&mut self, iter: I)
    where
        I: IntoIterator<Item = T>,
    {
        self.mutate_self_as_vec(|v| v.extend(iter));
    }
}

impl<T: Hash + Unpin> Hash for vector<T> {
    #[inline]
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.as_slice().hash(state);
    }
}

/// `vector` is `Send` if `T` is `Send` because it uniquely owns its contents.
unsafe impl<T: Send> Send for vector<T> {}

/// `vector` is `Sync` if `T` is `Sync` because it uniquely owns its contents.
unsafe impl<T: Sync> Sync for vector<T> {}

impl<T: PartialOrd + Unpin> PartialOrd<vector<T>> for vector<T> {
    #[inline]
    fn partial_cmp(&self, other: &vector<T>) -> Option<Ordering> {
        PartialOrd::partial_cmp(self.as_slice(), other.as_slice())
    }
}

impl<T: Eq> Eq for vector<T> {}

impl<T: Ord + Unpin> Ord for vector<T> {
    #[inline]
    fn cmp(&self, other: &Self) -> Ordering {
        Ord::cmp(self.as_slice(), other.as_slice())
    }
}

/// Helper method for creating a `Vec<T>` from raw parts.
///
/// # Safety
///
/// - `begin` must be a null or  `begin` must be a valid pointer and the memory
///   pointed by `begin` must be allocated with `StdAllocator`.
/// - `len` must be less than or equal to `capacity`.
/// - The first `len` values must be properly initialized values of type `T`.
/// - The size of `T `times the `capacity` (i.e. the allocated size in bytes)
///   needs to be the same size as the pointer was allocated with.
/// - `T` needs to have the same alignment as what `begin` was allocated with.
///
/// These requirements are always upheld by any `begin` that has been
/// allocated via Vec<T, StdAllocator>.
unsafe fn create_vec_from_raw_parts<T>(
    begin: *mut T,
    len: usize,
    capacity: usize,
) -> Vec<T, cpp_std_allocator::StdAllocator> {
    if begin.is_null() {
        Vec::new_in(cpp_std_allocator::StdAllocator {})
    } else {
        Vec::from_raw_parts_in(begin, len, capacity, cpp_std_allocator::StdAllocator {})
    }
}

mod iter {
    use super::alloc;
    use super::cpp_std_allocator;
    use super::vector;
    use core::fmt;
    use core::fmt::Debug;
    use core::iter::FusedIterator;
    /// An iterator that moves out of a vector.
    ///
    /// This type is currently a wrapper around `alloc::vec::IntoIter`,
    /// however users should not depend on it, and the wrapped iterator
    /// should not be made public. If the current implementation
    /// strategy stops working, the wrapped iterator will be replaced with
    /// a more complex implementation.
    pub struct VectorIntoIter<T>(alloc::vec::IntoIter<T, cpp_std_allocator::StdAllocator>);

    impl<T> VectorIntoIter<T> {
        pub fn new(v: alloc::vec::IntoIter<T, cpp_std_allocator::StdAllocator>) -> Self {
            VectorIntoIter(v)
        }

        /// Returns the remaining items of this iterator as a slice.
        #[inline]
        pub fn as_slice(&mut self) -> &[T] {
            self.0.as_slice()
        }

        /// Returns the remaining items of this iterator as a mutable slice.
        #[inline]
        pub fn as_mut_slice(&mut self) -> &mut [T] {
            self.0.as_mut_slice()
        }
    }

    impl<T> Iterator for VectorIntoIter<T> {
        type Item = T;

        #[inline]
        fn next(&mut self) -> Option<Self::Item> {
            self.0.next()
        }
        #[inline]
        fn size_hint(&self) -> (usize, Option<usize>) {
            self.0.size_hint()
        }

        // TODO(b/356638830): Uncomment when feature advance_by is stable
        // fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
        //     self.0.advance_by(n)
        // }

        #[inline]
        fn count(self) -> usize {
            self.0.len()
        }
    }

    impl<T> AsRef<[T]> for VectorIntoIter<T> {
        fn as_ref(&self) -> &[T] {
            self.0.as_ref()
        }
    }

    impl<T: fmt::Debug> Debug for VectorIntoIter<T> {
        fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
            self.0.fmt(f)
        }
    }

    impl<T: Unpin> Default for VectorIntoIter<T> {
        fn default() -> Self {
            vector::<T>::default().into_iter()
        }
    }

    impl<T> DoubleEndedIterator for VectorIntoIter<T> {
        #[inline]
        fn next_back(&mut self) -> Option<T> {
            self.0.next_back()
        }

        // TODO(b/356638830): Uncomment when feature advance_back_by is stable
        // #[inline]
        // fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
        //     self.0.advance_back_by()
        // }
    }

    impl<T> ExactSizeIterator for VectorIntoIter<T> {
        // TODO(b/356638830): Uncomment when feature is_empty is stable
        // #[inline]
        // fn is_empty(&self) -> bool {
        //     self.0.is_empty()
        // }
    }

    impl<T> FusedIterator for VectorIntoIter<T> {}
    // TODO(b/356638830): Uncomment when feature TrustedLen is stable
    // unsafe impl<T> TrustedLen for VectorIntoIter<T> {}
}

use iter::*;

impl<T: Unpin> IntoIterator for vector<T> {
    type Item = T;
    type IntoIter = VectorIntoIter<T>;
    fn into_iter(self) -> Self::IntoIter {
        #[allow(unused_unsafe)]
        unsafe {
            self.asan_unpoison_tail();
            let v = create_vec_from_raw_parts(self.begin as *mut _, self.len(), self.capacity());
            core::mem::forget(self);
            VectorIntoIter::new(v.into_iter())
        }
    }
}

impl<'a, T: Unpin> IntoIterator for &'a vector<T> {
    type Item = &'a T;
    type IntoIter = slice::Iter<'a, T>;

    fn into_iter(self) -> Self::IntoIter {
        self.iter()
    }
}

impl<'a, T: Unpin> IntoIterator for &'a mut vector<T> {
    type Item = &'a mut T;
    type IntoIter = slice::IterMut<'a, T>;

    fn into_iter(self) -> Self::IntoIter {
        self.iter_mut()
    }
}

impl<T: Unpin> FromIterator<T> for vector<T> {
    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
        let mut v = Self::new();
        v.mutate_self_as_vec(|u| {
            u.extend(iter);
        });
        v
    }
}

impl<T: Unpin> From<vector<T>> for alloc::vec::Vec<T> {
    fn from(v: vector<T>) -> alloc::vec::Vec<T> {
        v.into_vec()
    }
}

impl<T: Unpin> From<Vec<T>> for vector<T> {
    fn from(v: Vec<T>) -> Self {
        // Elements from `v` are moved. It would be more efficient to steal a buffer
        // from `v`. But `v` might have different allocator than vector.
        // TODO(b/356221873): Figure out conditions when it is possible to steal buffer
        // from `v`.
        let mut result = vector::<T>::with_capacity(v.len());
        result.mutate_self_as_vec(|u| {
            u.extend(v);
        });
        result
    }
}

impl<T: Unpin> From<Vec<T, cpp_std_allocator::StdAllocator>> for vector<T> {
    /// Creates a `vector<T>` from a `Vec<T, StdAllocator>`.
    ///
    /// Ownership of elements from `v` are taken by the returned `vector<T>`.
    fn from(mut v: Vec<T, cpp_std_allocator::StdAllocator>) -> Self {
        let mut result = vector::new();
        // Safety:
        //
        // It is safe since the memory is allocated with `Vec<T, StdAllocator>`.
        unsafe {
            result.set_begin_len_capacity(v.as_mut_ptr(), v.len(), v.capacity());
            core::mem::forget(v);

            result.asan_poison_tail();
            result
        }
    }
}

impl<T: Unpin + Clone> From<&[T]> for vector<T> {
    fn from(s: &[T]) -> Self {
        let mut result = vector::<T>::with_capacity(s.len());
        result.mutate_self_as_vec(|u| {
            u.extend_from_slice(s);
        });
        result
    }
}

impl<T: Unpin + Clone> From<&mut [T]> for vector<T> {
    fn from(slice: &mut [T]) -> Self {
        let mut result = vector::with_capacity(slice.len());
        result.mutate_self_as_vec(|u| {
            u.extend_from_slice(slice);
        });
        result
    }
}

impl<T: Unpin + Clone, const N: usize> From<&[T; N]> for vector<T> {
    fn from(s: &[T; N]) -> Self {
        Self::from(s.as_slice())
    }
}
impl<T: Unpin + Clone, const N: usize> From<&mut [T; N]> for vector<T> {
    fn from(s: &mut [T; N]) -> Self {
        Self::from(s.as_mut_slice())
    }
}

impl<T: Unpin + Clone, const N: usize> From<[T; N]> for vector<T> {
    fn from(s: [T; N]) -> Self {
        Self::from(s.as_slice())
    }
}
