Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/rust/fallible_collections/src/   (Firefox Browser Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 4 kB image not shown  

Quelle  boxed.rs

  Sprache: Rust
 

//! Implement Fallible Box
use super::TryClone;
use crate::TryReserveError;
use alloc::alloc::Layout;
use alloc::boxed::Box;
use core::borrow::Borrow;
use core::ops::Deref;
use core::ptr::NonNull;

/// trait to implement Fallible Box
pub trait FallibleBox<T> {
    /// try creating a new box, returning a Result<Box<T>,
    /// TryReserveError> if allocation failed
    fn try_new(t: T) -> Result<Self, TryReserveError>
    where
        Self: Sized;
}
/// TryBox is a thin wrapper around alloc::boxed::Box to provide support for
/// fallible allocation.
///
/// See the crate documentation for more.
pub struct TryBox<T> {
    inner: Box<T>,
}

impl<T> TryBox<T> {
    #[inline]
    pub fn try_new(t: T) -> Result<Self, TryReserveError> {
        Ok(Self {
            inner: <Box<T> as FallibleBox<T>>::try_new(t)?,
        })
    }

    #[inline(always)]
    pub fn into_raw(b: TryBox<T>) -> *mut T {
        Box::into_raw(b.inner)
    }

    /// # Safety
    ///
    /// See std::boxed::from_raw
    #[inline(always)]
    pub unsafe fn from_raw(raw: *mut T) -> Self {
        Self {
            inner: Box::from_raw(raw),
        }
    }
}

impl<T: TryClone> TryClone for TryBox<T> {
    fn try_clone(&self) -> Result<Self, TryReserveError> {
        let clone: T = (*self.inner).try_clone()?;
        Self::try_new(clone)
    }
}

impl<T> Deref for TryBox<T> {
    type Target = T;

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

fn alloc(layout: Layout) -> Result<NonNull<u8>, TryReserveError> {
    #[cfg(all(feature = "unstable", not(feature = "rust_1_57")))] // requires allocator_api
    {
        use alloc::collections::TryReserveErrorKind;
        use core::alloc::Allocator;
        alloc::alloc::Global
            .allocate(layout)
            .map_err(|_e| {
                TryReserveErrorKind::AllocError {
                    layout,
                    non_exhaustive: (),
                }
                .into()
            })
            .map(|v| v.cast())
    }
    #[cfg(any(not(feature = "unstable"), feature = "rust_1_57"))]
    {
        match layout.size() {
            0 => {
                // Required for alloc safety
                // See https://doc.rust-lang.org/stable/std/alloc/trait.GlobalAlloc.html#safety-1
                Ok(NonNull::dangling())
            }
            1..=core::usize::MAX => {
                let ptr = unsafe { alloc::alloc::alloc(layout) };
                core::ptr::NonNull::new(ptr).ok_or(TryReserveError::AllocError { layout })
            }
            _ => unreachable!("size must be non-negative"),
        }
    }
}

impl<T> FallibleBox<T> for Box<T> {
    fn try_new(t: T) -> Result<Self, TryReserveError> {
        let layout = Layout::for_value(&t);
        let ptr = alloc(layout)?.as_ptr() as *mut T;
        unsafe {
            core::ptr::write(ptr, t);
            Ok(Box::from_raw(ptr))
        }
    }
}

impl<T: TryClone> TryClone for Box<T> {
    #[inline]
    fn try_clone(&self) -> Result<Self, TryReserveError> {
        <Self as FallibleBox<T>>::try_new(Borrow::<T>::borrow(self).try_clone()?)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn boxed() {
        let mut v = <Box<_> as FallibleBox<_>>::try_new(5).unwrap();
        assert_eq!(*v, 5);
        *v = 3;
        assert_eq!(*v, 3);
    }
    // #[test]
    // fn big_alloc() {
    //     let layout = Layout::from_size_align(1_000_000_000_000, 8).unwrap();
    //     let ptr = unsafe { alloc::alloc::alloc(layout) };
    //     assert!(ptr.is_null());
    // }

    #[test]
    fn trybox_zst() {
        let b = <Box<_> as FallibleBox<_>>::try_new(()).expect("ok");
        assert_eq!(b, Box::new(()));
    }

    struct NonCopyType;

    #[test]
    fn trybox_deref() {
        let try_box: TryBox<NonCopyType> = TryBox::try_new(NonCopyType {}).unwrap();
        let _derefed: &NonCopyType = try_box.deref();
    }

    #[test]
    fn trybox_as_deref() {
        let try_box_option: Option<TryBox<NonCopyType>> =
            Some(TryBox::try_new(NonCopyType).unwrap());
        let _ref_option: Option<&NonCopyType> = try_box_option.as_deref();
    }
}

Messung V0.5 in Prozent
C=88 H=94 G=90

¤ Dauer der Verarbeitung: 0.17 Sekunden  (vorverarbeitet am  2026-06-27) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.