nalgebra/base/
uninit.rs

1use std::mem::MaybeUninit;
2
3/// This trait is used to write code that may work on matrices that may or may not
4/// be initialized.
5///
6/// This trait is used to describe how a value must be accessed to initialize it or
7/// to retrieve a reference or mutable reference. Typically, a function accepting
8/// both initialized and uninitialized inputs should have a `Status: InitStatus<T>`
9/// type parameter. Then the methods of the `Status` can be used to access the element.
10///
11/// # Safety
12/// This trait must not be implemented outside of this crate.
13pub unsafe trait InitStatus<T>: Copy {
14    /// The type of the values with the initialization status described by `Self`.
15    type Value;
16
17    /// Initialize the given element.
18    fn init(out: &mut Self::Value, t: T);
19
20    /// Retrieve a reference to the element, assuming that it is initialized.
21    ///
22    /// # Safety
23    /// This is unsound if the referenced value isn’t initialized.
24    unsafe fn assume_init_ref(t: &Self::Value) -> &T;
25
26    /// Retrieve a mutable reference to the element, assuming that it is initialized.
27    ///
28    /// # Safety
29    /// This is unsound if the referenced value isn’t initialized.
30    unsafe fn assume_init_mut(t: &mut Self::Value) -> &mut T;
31}
32
33#[derive(Copy, Clone, Debug, PartialEq, Eq)]
34/// A type implementing `InitStatus` indicating that the value is completely initialized.
35pub struct Init;
36#[derive(Copy, Clone, Debug, PartialEq, Eq)]
37/// A type implementing `InitStatus` indicating that the value is completely uninitialized.
38pub struct Uninit;
39
40unsafe impl<T> InitStatus<T> for Init {
41    type Value = T;
42
43    #[inline(always)]
44    fn init(out: &mut T, t: T) {
45        *out = t;
46    }
47
48    #[inline(always)]
49    unsafe fn assume_init_ref(t: &T) -> &T {
50        t
51    }
52
53    #[inline(always)]
54    unsafe fn assume_init_mut(t: &mut T) -> &mut T {
55        t
56    }
57}
58
59unsafe impl<T> InitStatus<T> for Uninit {
60    type Value = MaybeUninit<T>;
61
62    #[inline(always)]
63    fn init(out: &mut MaybeUninit<T>, t: T) {
64        *out = MaybeUninit::new(t);
65    }
66
67    #[inline(always)]
68    unsafe fn assume_init_ref(t: &MaybeUninit<T>) -> &T {
69        &*t.as_ptr() // TODO: use t.assume_init_ref()
70    }
71
72    #[inline(always)]
73    unsafe fn assume_init_mut(t: &mut MaybeUninit<T>) -> &mut T {
74        &mut *t.as_mut_ptr() // TODO: use t.assume_init_mut()
75    }
76}