Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  vec.rs   Sprache: unbekannt

 
//! Implement Fallible Vec
use super::TryClone;
use crate::TryReserveError;
#[allow(unused_imports)]
use alloc::alloc::{alloc, realloc, Layout};
use alloc::vec::Vec;
use core::convert::TryInto as _;

#[cfg(feature = "unstable")]
#[macro_export]
/// macro trying to create a vec, return a
/// Result<Vec<T>,TryReserveError>
macro_rules! try_vec {
   ($elem:expr; $n:expr) => (
        $crate::vec::try_from_elem($elem, $n)
    );
    ($($x:expr),*) => (
        match <alloc::boxed::Box<_> as $crate::boxed::FallibleBox<_>>::try_new([$($x),*]) {
            Err(e) => Err(e),
            Ok(b) => Ok(<[_]>::into_vec(b)),
        }
    );
    ($($x:expr,)*) => ($crate::try_vec![$($x),*])
}

/// trait implementing all fallible methods on vec
pub trait FallibleVec<T> {
    /// see reserve
    fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError>;
    /// see push
    fn try_push(&mut self, elem: T) -> Result<(), TryReserveError>;
    /// try push and give back ownership in case of error
    fn try_push_give_back(&mut self, elem: T) -> Result<(), (T, TryReserveError)>;
    /// see with capacity, (Self must be sized by the constraint of Result)
    fn try_with_capacity(capacity: usize) -> Result<Self, TryReserveError>
    where
        Self: core::marker::Sized;
    /// see insert
    fn try_insert(&mut self, index: usize, element: T) -> Result<(), (T, TryReserveError)>;
    /// see append
    fn try_append(&mut self, other: &mut Self) -> Result<(), TryReserveError>;
    /// see resize, only works when the `value` implements Copy, otherwise, look at try_resize_no_copy
    fn try_resize(&mut self, new_len: usize, value: T) -> Result<(), TryReserveError>
    where
        T: Copy + Clone;
    fn try_resize_with<F>(&mut self, new_len: usize, f: F) -> Result<(), TryReserveError>
    where
        F: FnMut() -> T;
    /// resize the vec by trying to clone the value repeatingly
    fn try_resize_no_copy(&mut self, new_len: usize, value: T) -> Result<(), TryReserveError>
    where
        T: TryClone;
    /// see resize, only works when the `value` implements Copy, otherwise, look at try_extend_from_slice_no_copy
    fn try_extend_from_slice(&mut self, other: &[T]) -> Result<(), TryReserveError>
    where
        T: Copy + Clone;
    /// extend the vec by trying to clone the value in `other`
    fn try_extend_from_slice_no_copy(&mut self, other: &[T]) -> Result<(), TryReserveError>
    where
        T: TryClone;
}

/// TryVec is a thin wrapper around alloc::vec::Vec to provide support for
/// fallible allocation.
///
/// See the crate documentation for more.
#[derive(PartialEq)]
pub struct TryVec<T> {
    inner: Vec<T>,
}

impl<T> Default for TryVec<T> {
    #[inline(always)]
    fn default() -> Self {
        Self {
            inner: Default::default(),
        }
    }
}

impl<T: core::fmt::Debug> core::fmt::Debug for TryVec<T> {
    #[inline]
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        self.inner.fmt(f)
    }
}

impl<T> TryVec<T> {
    #[inline(always)]
    pub fn new() -> Self {
        Self { inner: Vec::new() }
    }

    #[inline]
    pub fn with_capacity(capacity: usize) -> Result<Self, TryReserveError> {
        Ok(Self {
            inner: FallibleVec::try_with_capacity(capacity)?,
        })
    }

    #[inline(always)]
    pub fn append(&mut self, other: &mut Self) -> Result<(), TryReserveError> {
        FallibleVec::try_append(&mut self.inner, &mut other.inner)
    }

    #[inline(always)]
    pub fn as_mut_slice(&mut self) -> &mut [T] {
        self
    }

    #[inline(always)]
    pub fn as_slice(&self) -> &[T] {
        self
    }

    #[inline(always)]
    pub fn clear(&mut self) {
        self.inner.clear()
    }

    #[cfg(test)]
    pub fn into_inner(self) -> Vec<T> {
        self.inner
    }

    #[inline(always)]
    pub fn is_empty(&self) -> bool {
        self.inner.is_empty()
    }

    #[inline(always)]
    pub fn iter_mut(&mut self) -> IterMut<T> {
        IterMut {
            inner: self.inner.iter_mut(),
        }
    }

    #[inline(always)]
    pub fn iter(&self) -> Iter<T> {
        Iter {
            inner: self.inner.iter(),
        }
    }

    #[inline(always)]
    pub fn pop(&mut self) -> Option<T> {
        self.inner.pop()
    }

    #[inline(always)]
    pub fn push(&mut self, value: T) -> Result<(), TryReserveError> {
        FallibleVec::try_push(&mut self.inner, value)
    }

    #[inline(always)]
    pub fn reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
        FallibleVec::try_reserve(&mut self.inner, additional)
    }

    #[inline(always)]
    pub fn resize_with<F>(&mut self, new_len: usize, f: F) -> Result<(), TryReserveError>
    where
        F: FnMut() -> T,
    {
        FallibleVec::try_resize_with(&mut self.inner, new_len, f)
    }
}

impl<T: TryClone> TryClone for TryVec<T> {
    #[inline]
    fn try_clone(&self) -> Result<Self, TryReserveError> {
        self.as_slice().try_into()
    }
}

impl<T: TryClone> TryVec<TryVec<T>> {
    pub fn concat(&self) -> Result<TryVec<T>, TryReserveError> {
        let size = self.iter().map(|v| v.inner.len()).sum();
        let mut result = TryVec::with_capacity(size)?;
        for v in self.iter() {
            result.inner.try_extend_from_slice_no_copy(&v.inner)?;
        }
        Ok(result)
    }
}

impl<T: TryClone> TryVec<T> {
    #[inline(always)]
    pub fn extend_from_slice(&mut self, other: &[T]) -> Result<(), TryReserveError> {
        self.inner.try_extend_from_slice_no_copy(other)
    }
}

impl<T> IntoIterator for TryVec<T> {
    type Item = T;
    type IntoIter = alloc::vec::IntoIter<T>;

    #[inline(always)]
    fn into_iter(self) -> Self::IntoIter {
        self.inner.into_iter()
    }
}

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

    #[inline(always)]
    fn into_iter(self) -> Self::IntoIter {
        self.inner.iter()
    }
}

#[cfg(feature = "std_io")]
pub mod std_io {
    use super::*;
    use std::io::{self, Read, Take, Write};

    pub trait TryRead {
        fn try_read_to_end(&mut self, buf: &mut TryVec<u8>) -> io::Result<usize>;

        #[inline]
        fn read_into_try_vec(&mut self) -> io::Result<TryVec<u8>> {
            let mut buf = TryVec::new();
            self.try_read_to_end(&mut buf)?;
            Ok(buf)
        }
    }

    impl<T: Read> TryRead for Take<T> {
        /// This function reserves the upper limit of what `src` can generate before
        /// reading all bytes until EOF in this source, placing them into `buf`. If the
        /// allocation is unsuccessful, or reading from the source generates an error
        /// before reaching EOF, this will return an error. Otherwise, it will return
        /// the number of bytes read.
        ///
        /// Since `Take::limit()` may return a value greater than the number of bytes
        /// which can be read from the source, it's possible this function may fail
        /// in the allocation phase even though allocating the number of bytes available
        /// to read would have succeeded. In general, it is assumed that the callers
        /// have accurate knowledge of the number of bytes of interest and have created
        /// `src` accordingly.
        #[inline]
        fn try_read_to_end(&mut self, buf: &mut TryVec<u8>) -> io::Result<usize> {
            try_read_up_to(self, self.limit(), buf)
        }
    }

    /// Read up to `limit` bytes from `src`, placing them into `buf` and returning the
    /// number of bytes read. Space for `limit` additional bytes is reserved in `buf`, so
    /// this function will return an error if the allocation fails.
    pub fn try_read_up_to<R: Read>(
        src: &mut R,
        limit: u64,
        buf: &mut TryVec<u8>,
    ) -> io::Result<usize> {
        let additional = limit
            .try_into()
            .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
        buf.reserve(additional)
            .map_err(|_| io::Error::new(io::ErrorKind::Other, "reserve allocation failed"))?;
        let bytes_read = src.take(limit).read_to_end(&mut buf.inner)?;
        Ok(bytes_read)
    }

    impl Write for TryVec<u8> {
        fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
            self.extend_from_slice(buf)
                .map_err(|_| io::Error::new(io::ErrorKind::Other, "extend_from_slice failed"))?;
            Ok(buf.len())
        }

        #[inline(always)]
        fn flush(&mut self) -> io::Result<()> {
            Ok(())
        }
    }

    #[cfg(test)]
    mod tests {
        use super::*;

        #[test]
        fn try_read_to_end() {
            let mut src = b"1234567890".take(5);
            let mut buf = TryVec::new();
            src.try_read_to_end(&mut buf).unwrap();
            assert_eq!(buf.len(), 5);
            assert_eq!(buf, b"12345".as_ref());
        }

        #[test]
        fn read_into_try_vec() {
            let mut src = b"1234567890".take(5);
            let buf = src.read_into_try_vec().unwrap();
            assert_eq!(buf.len(), 5);
            assert_eq!(buf, b"12345".as_ref());
        }

        #[test]
        fn read_into_try_vec_oom() {
            let mut src = b"1234567890".take(core::usize::MAX.try_into().expect("usize < u64"));
            assert!(src.read_into_try_vec().is_err());
        }

        #[test]
        fn try_read_up_to() {
            let src = b"1234567890";
            let mut buf = TryVec::new();
            super::try_read_up_to(&mut src.as_ref(), 5, &mut buf).unwrap();
            assert_eq!(buf.len(), 5);
            assert_eq!(buf, b"12345".as_ref());
        }

        #[test]
        fn try_read_up_to_oom() {
            let src = b"1234567890";
            let mut buf = TryVec::new();
            let limit = core::usize::MAX.try_into().expect("usize < u64");
            let res = super::try_read_up_to(&mut src.as_ref(), limit, &mut buf);
            assert!(res.is_err());
        }
    }
}

impl<T: PartialEq> PartialEq<Vec<T>> for TryVec<T> {
    #[inline(always)]
    fn eq(&self, other: &Vec<T>) -> bool {
        self.inner.eq(other)
    }
}

impl<'a, T: PartialEq> PartialEq<&'a [T]> for TryVec<T> {
    #[inline(always)]
    fn eq(&self, other: &&[T]) -> bool {
        self.inner.eq(other)
    }
}

impl PartialEq<&str> for TryVec<u8> {
    #[inline]
    fn eq(&self, other: &&str) -> bool {
        self.as_slice() == other.as_bytes()
    }
}

impl core::convert::AsRef<[u8]> for TryVec<u8> {
    #[inline(always)]
    fn as_ref(&self) -> &[u8] {
        self.inner.as_ref()
    }
}

impl<T> core::convert::From<Vec<T>> for TryVec<T> {
    #[inline(always)]
    fn from(value: Vec<T>) -> Self {
        Self { inner: value }
    }
}

impl<T: TryClone> core::convert::TryFrom<&[T]> for TryVec<T> {
    type Error = TryReserveError;

    #[inline]
    fn try_from(value: &[T]) -> Result<Self, Self::Error> {
        let mut v = Self::new();
        v.inner.try_extend_from_slice_no_copy(value)?;
        Ok(v)
    }
}

impl core::convert::TryFrom<&str> for TryVec<u8> {
    type Error = TryReserveError;

    #[inline]
    fn try_from(value: &str) -> Result<Self, Self::Error> {
        let mut v = Self::new();
        v.extend_from_slice(value.as_bytes())?;
        Ok(v)
    }
}

impl<T> core::ops::Deref for TryVec<T> {
    type Target = [T];

    #[inline(always)]
    fn deref(&self) -> &[T] {
        self.inner.deref()
    }
}

impl<T> core::ops::DerefMut for TryVec<T> {
    fn deref_mut(&mut self) -> &mut [T] {
        self.inner.deref_mut()
    }
}

pub struct Iter<'a, T> {
    inner: alloc::slice::Iter<'a, T>,
}

impl<'a, T> Iterator for Iter<'a, T> {
    type Item = &'a T;

    #[inline(always)]
    fn next(&mut self) -> Option<Self::Item> {
        self.inner.next()
    }

    #[inline(always)]
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.inner.size_hint()
    }
}

pub struct IterMut<'a, T> {
    inner: alloc::slice::IterMut<'a, T>,
}

impl<'a, T> Iterator for IterMut<'a, T> {
    type Item = &'a mut T;

    #[inline(always)]
    fn next(&mut self) -> Option<Self::Item> {
        self.inner.next()
    }

    #[inline(always)]
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.inner.size_hint()
    }
}

/// Grow capacity exponentially
#[cold]
fn vec_try_reserve_for_growth<T>(v: &mut Vec<T>, additional: usize) -> Result<(), TryReserveError> {
    // saturating, because can't use CapacityOverflow here if rust_1_57 flag is enabled
    FallibleVec::try_reserve(v, additional.max(v.capacity().saturating_mul(2) - v.len()))
}

fn needs_to_grow<T>(v: &Vec<T>, len: usize) -> bool {
    v.len().checked_add(len).map_or(true, |needed| needed > v.capacity())
}

#[cfg(not(any(feature = "unstable", feature = "rust_1_57")))]
fn vec_try_reserve<T>(v: &mut Vec<T>, additional: usize) -> Result<(), TryReserveError> {
    let available = v.capacity().checked_sub(v.len()).expect("capacity >= len");
    if additional > available {
        let increase = additional
            .checked_sub(available)
            .expect("additional > available");
        let new_cap = v
            .capacity()
            .checked_add(increase)
            .ok_or(TryReserveError::CapacityOverflow)?;
        vec_try_extend(v, new_cap)?;
        debug_assert!(v.capacity() == new_cap);
    }

    Ok(())
}

#[cfg(not(any(feature = "unstable", feature = "rust_1_57")))]
fn vec_try_extend<T>(v: &mut Vec<T>, new_cap: usize) -> Result<(), TryReserveError> {
    let old_len = v.len();
    let old_cap: usize = v.capacity();

    if old_cap >= new_cap {
        return Ok(());
    }

    let elem_size = core::mem::size_of::<T>();
    let new_alloc_size = new_cap
        .checked_mul(elem_size)
        .filter(|size| *size <= isize::MAX as usize)
        .ok_or(TryReserveError::CapacityOverflow)?;

    // required for alloc safety
    // See https://doc.rust-lang.org/stable/std/alloc/trait.GlobalAlloc.html#safety-1
    // Should be unreachable given prior `old_cap >= new_cap` check.
    assert!(new_alloc_size > 0);

    let align = core::mem::align_of::<T>();

    let (new_ptr, layout) = {
        if old_cap == 0 {
            let layout = Layout::from_size_align(new_alloc_size, align).expect("Invalid layout");
            let new_ptr = unsafe { alloc(layout) };
            (new_ptr, layout)
        } else {
            let old_alloc_size = old_cap
                .checked_mul(elem_size)
                .ok_or(TryReserveError::CapacityOverflow)?;
            let layout = Layout::from_size_align(old_alloc_size, align).expect("Invalid layout");
            let new_ptr = unsafe { realloc(v.as_mut_ptr() as *mut u8, layout, new_alloc_size) };
            (new_ptr, layout)
        }
    };

    if new_ptr.is_null() {
        return Err(TryReserveError::AllocError { layout });
    }

    let new_vec = unsafe { Vec::from_raw_parts(new_ptr.cast(), old_len, new_cap) };

    core::mem::forget(core::mem::replace(v, new_vec));
    Ok(())
}

impl<T> FallibleVec<T> for Vec<T> {
    #[inline(always)]
    fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
        #[cfg(all(feature = "unstable", not(feature = "rust_1_57")))]
        {
            self.try_reserve(additional)
        }

        #[cfg(all(not(feature = "unstable"), not(feature = "rust_1_57")))]
        {
            vec_try_reserve(self, additional)
        }

        #[cfg(feature = "rust_1_57")]
        {
            // TryReserveError is an opaque type in 1.57
            self.try_reserve(additional).map_err(|_| {
                crate::make_try_reserve_error(self.len(), additional, core::mem::size_of::<T>(), core::mem::align_of::<T>())
            })
        }
    }

    #[inline]
    fn try_push(&mut self, elem: T) -> Result<(), TryReserveError> {
        if self.len() == self.capacity() {
            vec_try_reserve_for_growth(self, 1)?;
        }
        Ok(self.push(elem))
    }

    #[inline]
    fn try_push_give_back(&mut self, elem: T) -> Result<(), (T, TryReserveError)> {
        if self.len() == self.capacity() {
            if let Err(e) = vec_try_reserve_for_growth(self, 1) {
                return Err((elem, e));
            }
        }
        Ok(self.push(elem))
    }

    #[inline]
    fn try_with_capacity(capacity: usize) -> Result<Self, TryReserveError>
    where
        Self: core::marker::Sized,
    {
        let mut n = Self::new();
        FallibleVec::try_reserve(&mut n, capacity)?;
        Ok(n)
    }

    #[inline]
    fn try_insert(&mut self, index: usize, element: T) -> Result<(), (T, TryReserveError)> {
        if self.len() == self.capacity() {
            if let Err(e) = vec_try_reserve_for_growth(self, 1) {
                return Err((element, e));
            }
        }
        Ok(self.insert(index, element))
    }
    #[inline]
    fn try_append(&mut self, other: &mut Self) -> Result<(), TryReserveError> {
        FallibleVec::try_reserve(self, other.len())?;
        Ok(self.append(other))
    }
    fn try_resize(&mut self, new_len: usize, value: T) -> Result<(), TryReserveError>
    where
        T: Copy + Clone,
    {
        let len = self.len();
        if new_len > len {
            FallibleVec::try_reserve(self, new_len - len)?;
        }
        Ok(self.resize(new_len, value))
    }
    fn try_resize_with<F>(&mut self, new_len: usize, f: F) -> Result<(), TryReserveError>
    where
        F: FnMut() -> T,
    {
        let len = self.len();
        if new_len > len {
            FallibleVec::try_reserve(self, new_len - len)?;
        }
        Ok(self.resize_with(new_len, f))
    }
    fn try_resize_no_copy(&mut self, new_len: usize, value: T) -> Result<(), TryReserveError>
    where
        T: TryClone,
    {
        let len = self.len();

        if new_len > len {
            self.try_extend_with(new_len - len, TryExtendElement(value))
        } else {
            Ok(self.truncate(new_len))
        }
    }
    #[inline]
    fn try_extend_from_slice(&mut self, other: &[T]) -> Result<(), TryReserveError>
    where
        T: Clone,
    {
        if needs_to_grow(self, other.len()) {
            vec_try_reserve_for_growth(self, other.len())?;
        }
        Ok(self.extend_from_slice(other))
    }
    fn try_extend_from_slice_no_copy(&mut self, other: &[T]) -> Result<(), TryReserveError>
    where
        T: TryClone,
    {
        if needs_to_grow(self, other.len()) {
            vec_try_reserve_for_growth(self, other.len())?;
        }
        let mut len = self.len();
        let mut iterator = other.iter();
        while let Some(element) = iterator.next() {
            unsafe {
                core::ptr::write(self.as_mut_ptr().add(len), element.try_clone()?);
                // NB can't overflow since we would have had to alloc the address space
                len += 1;
                self.set_len(len);
            }
        }
        Ok(())
    }
}

trait ExtendWith<T> {
    fn next(&mut self) -> Result<T, TryReserveError>;
    fn last(self) -> T;
}

struct TryExtendElement<T: TryClone>(T);
impl<T: TryClone> ExtendWith<T> for TryExtendElement<T> {
    #[inline(always)]
    fn next(&mut self) -> Result<T, TryReserveError> {
        self.0.try_clone()
    }
    #[inline(always)]
    fn last(self) -> T {
        self.0
    }
}

trait TryExtend<T> {
    fn try_extend_with<E: ExtendWith<T>>(
        &mut self,
        n: usize,
        value: E,
    ) -> Result<(), TryReserveError>;
}

impl<T> TryExtend<T> for Vec<T> {
    /// Extend the vector by `n` values, using the given generator.
    fn try_extend_with<E: ExtendWith<T>>(
        &mut self,
        n: usize,
        mut value: E,
    ) -> Result<(), TryReserveError> {
        if needs_to_grow(self, n) {
            vec_try_reserve_for_growth(self, n)?;
        }

        unsafe {
            let mut ptr = self.as_mut_ptr().add(self.len());

            let mut local_len = self.len();
            // Write all elements except the last one
            for _ in 1..n {
                core::ptr::write(ptr, value.next()?);
                ptr = ptr.offset(1);
                // Increment the length in every step in case next() panics
                local_len += 1;
                self.set_len(local_len);
            }

            if n > 0 {
                // We can write the last element directly without cloning needlessly
                core::ptr::write(ptr, value.last());
                local_len += 1;
                self.set_len(local_len);
            }

            // len set by scope guard
        }
        Ok(())
    }
}

trait Truncate {
    fn truncate(&mut self, len: usize);
}

impl<T> Truncate for Vec<T> {
    fn truncate(&mut self, len: usize) {
        let current_len = self.len();
        unsafe {
            let mut ptr = self.as_mut_ptr().add(current_len);
            // Set the final length at the end, keeping in mind that
            // dropping an element might panic. Works around a missed
            // optimization, as seen in the following issue:
            // https://github.com/rust-lang/rust/issues/51802
            let mut local_len = self.len();

            // drop any extra elements
            for _ in len..current_len {
                ptr = ptr.offset(-1);
                core::ptr::drop_in_place(ptr);
                local_len -= 1;
                self.set_len(local_len);
            }
        }
    }
}

/// try creating a vec from an `elem` cloned `n` times, see std::from_elem
#[cfg(feature = "unstable")]
pub fn try_from_elem<T: TryClone>(elem: T, n: usize) -> Result<Vec<T>, TryReserveError> {
    <T as SpecFromElem>::try_from_elem(elem, n)
}

// Specialization trait used for Vec::from_elem
#[cfg(feature = "unstable")]
trait SpecFromElem: Sized {
    fn try_from_elem(elem: Self, n: usize) -> Result<Vec<Self>, TryReserveError>;
}

#[cfg(feature = "unstable")]
impl<T: TryClone> SpecFromElem for T {
    default fn try_from_elem(elem: Self, n: usize) -> Result<Vec<T>, TryReserveError> {
        let mut v = Vec::new();
        v.try_resize_no_copy(n, elem)?;
        Ok(v)
    }
}

#[cfg(feature = "unstable")]
impl SpecFromElem for u8 {
    #[inline]
    fn try_from_elem(elem: u8, n: usize) -> Result<Vec<u8>, TryReserveError> {
        unsafe {
            let mut v: Vec<u8> = FallibleVec::try_with_capacity(n)?;
            core::ptr::write_bytes(v.as_mut_ptr(), elem, n);
            v.set_len(n);
            Ok(v)
        }
    }
}

impl<T: TryClone> TryClone for Vec<T> {
    #[inline]
    fn try_clone(&self) -> Result<Self, TryReserveError>
    where
        Self: core::marker::Sized,
    {
        let mut v = Vec::new();
        v.try_extend_from_slice_no_copy(self)?;
        Ok(v)
    }
}

pub trait TryFromIterator<I>: Sized {
    fn try_from_iterator<T: IntoIterator<Item = I>>(iterator: T) -> Result<Self, TryReserveError>;
}

impl<I> TryFromIterator<I> for Vec<I> {
    fn try_from_iterator<T: IntoIterator<Item = I>>(iterator: T) -> Result<Self, TryReserveError>
    where
        T: IntoIterator<Item = I>,
    {
        let mut new = Self::new();
        for i in iterator {
            new.try_push(i)?;
        }
        Ok(new)
    }
}

pub trait TryCollect<I> {
    fn try_collect<C: TryFromIterator<I>>(self) -> Result<C, TryReserveError>;
}

impl<I, T> TryCollect<I> for T
where
    T: IntoIterator<Item = I>,
{
    #[inline(always)]
    fn try_collect<C: TryFromIterator<I>>(self) -> Result<C, TryReserveError> {
        C::try_from_iterator(self)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    #[cfg(feature = "unstable")]
    fn vec() {
        // let v: Vec<u8> = from_elem(1, 10);
        let v: Vec<Vec<u8>> = try_vec![try_vec![42; 10].unwrap(); 100].unwrap();
        println!("{:?}", v);
        let v2 = try_vec![0, 1, 2];
        println!("{:?}", v2);
        assert_eq!(2 + 2, 4);
    }

    #[test]
    fn try_clone_vec() {
        // let v: Vec<u8> = from_elem(1, 10);
        let v = vec![42; 100];
        assert_eq!(v.try_clone().unwrap(), v);
    }

    #[test]
    fn try_clone_oom() {
        let layout = Layout::new::<u8>();
        let v =
            unsafe { Vec::<u8>::from_raw_parts(alloc(layout), core::isize::MAX as usize, core::isize::MAX as usize) };
        assert!(v.try_clone().is_err());
    }

    #[test]
    fn tryvec_try_clone_oom() {
        let layout = Layout::new::<u8>();
        let inner =
            unsafe { Vec::<u8>::from_raw_parts(alloc(layout), core::isize::MAX as usize, core::isize::MAX as usize) };
        let tv = TryVec { inner };
        assert!(tv.try_clone().is_err());
    }

    // #[test]
    // fn try_out_of_mem() {
    //     let v = try_vec![42_u8; 1000000000];
    //     assert_eq!(v.try_clone().unwrap(), v);
    // }

    #[test]
    fn oom() {
        let mut vec: Vec<char> = Vec::new();
        match FallibleVec::try_reserve(&mut vec, core::usize::MAX / std::mem::size_of::<char>()) {
            Ok(_) => panic!("it should be OOM"),
            _ => (),
        }
        match FallibleVec::try_reserve(&mut vec, core::usize::MAX) {
            Ok(_) => panic!("it should be OOM"),
            _ => (),
        }
    }

    #[test]
    fn tryvec_oom() {
        let mut vec: TryVec<char> = TryVec::new();
        match vec.reserve(core::usize::MAX / std::mem::size_of::<char>()) {
            Ok(_) => panic!("it should be OOM"),
            _ => (),
        }
        match vec.reserve(core::usize::MAX) {
            Ok(_) => panic!("it should be OOM"),
            _ => (),
        }
    }

    #[test]
    fn try_reserve() {
        let mut vec: Vec<_> = vec![1];
        let additional_room = vec.capacity() - vec.len();
        let additional = additional_room + 1;
        let old_cap = vec.capacity();
        FallibleVec::try_reserve(&mut vec, additional).unwrap();
        assert!(vec.capacity() > old_cap);
    }

    #[test]
    fn tryvec_reserve() {
        let mut vec: TryVec<_> = vec![1].into();
        let old_cap = vec.inner.capacity();
        let new_cap = old_cap + 1;
        vec.reserve(new_cap).unwrap();
        assert!(vec.inner.capacity() >= new_cap);
    }

    #[test]
    fn try_reserve_idempotent() {
        let mut vec: Vec<_> = vec![1];
        let additional_room = vec.capacity() - vec.len();
        let additional = additional_room + 1;
        FallibleVec::try_reserve(&mut vec, additional).unwrap();
        let cap_after_reserve = vec.capacity();
        FallibleVec::try_reserve(&mut vec, additional).unwrap();
        assert_eq!(vec.capacity(), cap_after_reserve);
    }

    #[test]
    fn tryvec_reserve_idempotent() {
        let mut vec: TryVec<_> = vec![1].into();
        let old_cap = vec.inner.capacity();
        let new_cap = old_cap + 1;
        vec.reserve(new_cap).unwrap();
        let cap_after_reserve = vec.inner.capacity();
        vec.reserve(new_cap).unwrap();
        assert_eq!(cap_after_reserve, vec.inner.capacity());
    }

    #[test]
    fn capacity_overflow() {
        let mut vec: Vec<_> = vec![1];
        match FallibleVec::try_reserve(&mut vec, core::usize::MAX) {
            Ok(_) => panic!("capacity calculation should overflow"),
            _ => (),
        }
    }

    #[test]
    fn tryvec_capacity_overflow() {
        let mut vec: TryVec<_> = vec![1].into();
        match vec.reserve(core::usize::MAX) {
            Ok(_) => panic!("capacity calculation should overflow"),
            _ => (),
        }
    }

    #[test]
    fn extend_from_slice() {
        let mut vec: Vec<u8> = b"foo".as_ref().into();
        vec.shrink_to_fit();
        vec.reserve(5);
        assert_eq!(8, vec.capacity());
        vec.try_extend_from_slice(b"bar").unwrap();
        assert_eq!(vec, b"foobar".as_ref());
        vec.try_extend_from_slice(b"1").unwrap();
        assert_eq!(vec, b"foobar1".as_ref());
        assert_eq!(8, vec.capacity());
        vec.try_extend_from_slice(b"11").unwrap();
        assert_eq!(16, vec.capacity());
    }

    #[test]
    fn tryvec_extend_from_slice() {
        let mut vec: TryVec<u8> = b"foo".as_ref().try_into().unwrap();
        vec.extend_from_slice(b"bar").unwrap();
        assert_eq!(vec, b"foobar".as_ref());
    }

    #[test]
    #[cfg(not(any(feature = "unstable", feature = "rust_1_57")))]
    fn try_extend_zst() {
        let mut vec: Vec<()> = Vec::new();
        assert_eq!(vec.capacity(), core::usize::MAX);
        assert!(vec_try_extend(&mut vec, 10).is_ok());
        assert!(vec_try_extend(&mut vec, core::usize::MAX).is_ok());
    }

    #[test]
    fn try_reserve_zst() {
        let mut vec: Vec<()> = Vec::new();
        assert!(FallibleVec::try_reserve(&mut vec, core::usize::MAX).is_ok());
    }
}

[ Dauer der Verarbeitung: 0.36 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge