2021-08-03 00:41:46 +08:00
|
|
|
|
use std::mem::MaybeUninit;
|
|
|
|
|
|
2021-08-03 23:26:56 +08:00
|
|
|
|
/// This trait is used to write code that may work on matrices that may or may not
|
|
|
|
|
/// be initialized.
|
|
|
|
|
///
|
|
|
|
|
/// This trait is used to describe how a value must be accessed to initialize it or
|
|
|
|
|
/// to retrieve a reference or mutable reference. Typically, a function accepting
|
|
|
|
|
/// both initialized and uninitialized inputs should have a `Status: InitStatus<T>`
|
|
|
|
|
/// type parameter. Then the methods of the `Status` can be used to access the element.
|
|
|
|
|
///
|
|
|
|
|
/// # Safety
|
|
|
|
|
/// This trait must not be implemented outside of this crate.
|
2021-08-03 00:41:46 +08:00
|
|
|
|
pub unsafe trait InitStatus<T>: Copy {
|
2021-08-03 23:26:56 +08:00
|
|
|
|
/// The type of the values with the initialization status described by `Self`.
|
2021-08-03 00:41:46 +08:00
|
|
|
|
type Value;
|
2021-08-03 23:26:56 +08:00
|
|
|
|
|
|
|
|
|
/// Initialize the given element.
|
2021-08-03 00:41:46 +08:00
|
|
|
|
fn init(out: &mut Self::Value, t: T);
|
2021-08-03 23:26:56 +08:00
|
|
|
|
|
|
|
|
|
/// Retrieve a reference to the element, assuming that it is initialized.
|
|
|
|
|
///
|
|
|
|
|
/// # Safety
|
|
|
|
|
/// This is unsound if the referenced value isn’t initialized.
|
2021-08-03 00:41:46 +08:00
|
|
|
|
unsafe fn assume_init_ref(t: &Self::Value) -> &T;
|
2021-08-03 23:26:56 +08:00
|
|
|
|
|
|
|
|
|
/// Retrieve a mutable reference to the element, assuming that it is initialized.
|
|
|
|
|
///
|
|
|
|
|
/// # Safety
|
|
|
|
|
/// This is unsound if the referenced value isn’t initialized.
|
2021-08-03 00:41:46 +08:00
|
|
|
|
unsafe fn assume_init_mut(t: &mut Self::Value) -> &mut T;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
2021-08-03 23:26:56 +08:00
|
|
|
|
/// A type implementing `InitStatus` indicating that the value is completely initialized.
|
2021-08-03 00:41:46 +08:00
|
|
|
|
pub struct Init;
|
|
|
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
2023-02-01 14:48:06 +08:00
|
|
|
|
/// A type implementing `InitStatus` indicating that the value is completely uninitialized.
|
2021-08-03 00:41:46 +08:00
|
|
|
|
pub struct Uninit;
|
|
|
|
|
|
|
|
|
|
unsafe impl<T> InitStatus<T> for Init {
|
|
|
|
|
type Value = T;
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn init(out: &mut T, t: T) {
|
|
|
|
|
*out = t;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
unsafe fn assume_init_ref(t: &T) -> &T {
|
|
|
|
|
t
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
unsafe fn assume_init_mut(t: &mut T) -> &mut T {
|
|
|
|
|
t
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsafe impl<T> InitStatus<T> for Uninit {
|
|
|
|
|
type Value = MaybeUninit<T>;
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn init(out: &mut MaybeUninit<T>, t: T) {
|
|
|
|
|
*out = MaybeUninit::new(t);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
unsafe fn assume_init_ref(t: &MaybeUninit<T>) -> &T {
|
2021-08-16 00:12:17 +08:00
|
|
|
|
&*t.as_ptr() // TODO: use t.assume_init_ref()
|
2021-08-03 00:41:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
unsafe fn assume_init_mut(t: &mut MaybeUninit<T>) -> &mut T {
|
2021-08-16 00:12:17 +08:00
|
|
|
|
&mut *t.as_mut_ptr() // TODO: use t.assume_init_mut()
|
2021-08-03 00:41:46 +08:00
|
|
|
|
}
|
|
|
|
|
}
|