1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
use core::borrow::{Borrow, BorrowMut};
use core::mem::MaybeUninit;
use core::ops::{Deref, DerefMut};

use crate::traits::{Initialize, InitializeVectored, TrustedDeref};

/// A wrapper over `T` that assumes all of `T` to be initialized.
#[repr(transparent)]
#[derive(Clone, Copy, Default)]
pub struct AssertInit<T> {
    inner: T,
}

impl<T> AssertInit<T> {
    /// Wrap a possibly-uninitialized value `inner` into, assuming that it is fully initialized.
    ///
    /// # Safety
    ///
    /// The caller must ensure that `inner` is fully initialized before this function can be
    /// called.
    #[inline]
    pub const unsafe fn new_unchecked(inner: T) -> Self {
        Self { inner }
    }
    /// Cast `&[T]` to `&[AssertInit<T>]`.
    ///
    /// # Safety
    ///
    /// This is unsafe because the caller has to ensure that all instances of type `T`, uphold the
    /// initialization invariant.
    #[inline]
    pub unsafe fn cast_from_slices(inner_slices: &[T]) -> &[Self] {
        // SAFETY: This is safe because AssertInit is #[repr(transparent)], making the slices have
        // the same layout. The only contract that the caller has to follow, is that the data must
        // actually be initialized.
        core::slice::from_raw_parts(inner_slices.as_ptr() as *const Self, inner_slices.len())
    }
    /// Cast `&mut [T]` to `&mut [AssertInit<T>]`.
    ///
    /// # Safety
    ///
    /// This is unsafe because the caller has to ensure that all instances of type `T`, uphold the
    /// initialization invariant.
    #[inline]
    pub unsafe fn cast_from_slices_mut(inner_slices: &mut [T]) -> &mut [Self] {
        // SAFETY: This is safe because AssertInit is #[repr(transparent)], making the slices have
        // the same layout. The only contract that the caller has to follow, is that the data must
        // actually be initialized.
        core::slice::from_raw_parts_mut(inner_slices.as_ptr() as *mut Self, inner_slices.len())
    }
    /// Cast `&[AssertInit<T>]` to `&mut [AssertInit<T>]`.
    #[inline]
    pub fn cast_to_uninit_slices(selves: &[Self]) -> &[T] {
        unsafe {
            // SAFETY: This is safe because AssertInit is #[repr(transparent)], making the slices have the
            // same layout.
            //
            // Since the returned slice is immutable, nothing can be deinitialized.
            core::slice::from_raw_parts(selves.as_ptr() as *const T, selves.len())
        }
    }
    /// Cast `&mut [AssertInit<T>]` to `&mut [T]`.
    ///
    /// # Safety
    ///
    /// This is unsafe because it allows for de-initialization, which is very unlikely to happen by
    /// accident in practice, but which still would be unsound. The caller must simply never
    /// overwrite an already initialized value with [`MaybeUninit::uninit()`].
    #[inline]
    pub unsafe fn cast_to_uninit_slices_mut(selves: &mut [Self]) -> &mut [T] {
        // SAFETY: This is safe because AssertInit is #[repr(transparent)], making the slices have
        // the same layout. The only contract that the caller has to follow, is that the data must
        // never be de-initialized.
        core::slice::from_raw_parts_mut(selves.as_ptr() as *mut T, selves.len())
    }
    #[inline]
    pub fn from_ref(inner_slice: &T) -> &Self {
        unsafe {
            // SAFETY: This is safe because AssertInit is #[repr(transparent)], making the
            // references have the same layout. The only contract that the caller has to follow, is
            // that the data must actually be initialized.
            &*(inner_slice as *const T as *const Self)
        }
    }
    #[inline]
    pub fn from_mut(inner_slice: &mut T) -> &mut Self {
        unsafe {
            // SAFETY: This is safe because AssertInit is #[repr(transparent)], making the
            // references have the same layout. The only contract that the caller has to follow, is
            // that the data must actually be initialized.
            &mut *(inner_slice as *mut T as *mut Self)
        }
    }
    #[inline]
    pub fn into_inner(self) -> T {
        self.inner
    }
    #[inline]
    pub const fn inner(&self) -> &T {
        &self.inner
    }
    #[inline]
    pub fn inner_mut(&mut self) -> &mut T {
        &mut self.inner
    }
}
impl<T> AssertInit<T>
where
    T: Initialize,
{
    #[inline]
    pub fn get_init_ref(&self) -> &[T::Item] {
        unsafe { crate::cast_uninit_to_init_slice(self.inner().as_maybe_uninit_slice()) }
    }
    #[inline]
    pub fn get_init_mut(&mut self) -> &mut [T::Item] {
        unsafe {
            crate::cast_uninit_to_init_slice_mut(self.inner_mut().as_maybe_uninit_slice_mut())
        }
    }
    #[inline]
    pub fn get_uninit_ref(&self) -> &[MaybeUninit<T::Item>] {
        self.inner().as_maybe_uninit_slice()
    }
    /// Get a mutable slice to the inner uninitialized slice.
    ///
    /// # Safety
    ///
    /// Since the [`Initialize`] trait is generic over both already initialized and uninitialized
    /// types, it is unsafe to retrieve an uninitialized slice to already initialized data, because
    /// it allows for de-initialization. (This can happen when overwriting the resulting slice with
    /// [`MaybeUninit::uninit()`].
    #[inline]
    pub unsafe fn get_uninit_mut(&mut self) -> &mut [MaybeUninit<T::Item>] {
        self.inner_mut().as_maybe_uninit_slice_mut()
    }
}
impl<T> AsRef<[T::Item]> for AssertInit<T>
where
    T: Initialize,
{
    #[inline]
    fn as_ref(&self) -> &[T::Item] {
        self.get_init_ref()
    }
}
impl<T> AsMut<[T::Item]> for AssertInit<T>
where
    T: Initialize,
{
    #[inline]
    fn as_mut(&mut self) -> &mut [T::Item] {
        self.get_init_mut()
    }
}
impl<T> Borrow<[T::Item]> for AssertInit<T>
where
    T: Initialize,
{
    #[inline]
    fn borrow(&self) -> &[T::Item] {
        self.get_init_ref()
    }
}
impl<T> BorrowMut<[T::Item]> for AssertInit<T>
where
    T: Initialize,
{
    #[inline]
    fn borrow_mut(&mut self) -> &mut [T::Item] {
        self.get_init_mut()
    }
}
impl<T> Deref for AssertInit<T>
where
    T: Initialize,
{
    type Target = [T::Item];

    #[inline]
    fn deref(&self) -> &[T::Item] {
        self.get_init_ref()
    }
}
impl<T> DerefMut for AssertInit<T>
where
    T: Initialize,
{
    #[inline]
    fn deref_mut(&mut self) -> &mut [T::Item] {
        self.get_init_mut()
    }
}
impl<T> PartialEq for AssertInit<T>
where
    T: Initialize,
    T::Item: PartialEq,
{
    fn eq(&self, other: &Self) -> bool {
        self.get_init_ref() == other.get_init_ref()
    }
}
impl<T> Eq for AssertInit<T>
where
    T: Initialize,
    T::Item: Eq,
{
}
impl<T> PartialOrd for AssertInit<T>
where
    T: Initialize,
    T::Item: Ord,
{
    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
        Some(Ord::cmp(self, other))
    }
}
impl<T> Ord for AssertInit<T>
where
    T: Initialize,
    T::Item: Ord,
{
    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
        Ord::cmp(self.get_init_ref(), other.get_init_ref())
    }
}
impl<T> core::hash::Hash for AssertInit<T>
where
    T: Initialize,
    T::Item: core::hash::Hash,
{
    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
        self.get_init_ref().hash(state)
    }
}

#[repr(transparent)]
pub struct AssertInitVectors<I> {
    inner: I,
}
impl<I> AssertInitVectors<I> {
    pub const unsafe fn new_unchecked(inner: I) -> Self {
        Self { inner }
    }
    #[inline]
    pub fn into_inner(self) -> I {
        self.inner
    }
}
impl<T> From<AssertInitVectors<SingleVector<T>>> for AssertInit<T> {
    fn from(vectors: AssertInitVectors<SingleVector<T>>) -> Self {
        unsafe { Self::new_unchecked(vectors.into_inner().0) }
    }
}

#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[repr(transparent)]
pub struct SingleVector<T>(pub T);

impl<T> AsRef<[T]> for SingleVector<T> {
    #[inline]
    fn as_ref(&self) -> &[T] {
        core::slice::from_ref(&self.0)
    }
}
impl<T> AsMut<[T]> for SingleVector<T> {
    #[inline]
    fn as_mut(&mut self) -> &mut [T] {
        core::slice::from_mut(&mut self.0)
    }
}
impl<T> AsRef<T> for SingleVector<T> {
    #[inline]
    fn as_ref(&self) -> &T {
        &self.0
    }
}
impl<T> AsMut<T> for SingleVector<T> {
    #[inline]
    fn as_mut(&mut self) -> &mut T {
        &mut self.0
    }
}
impl<T> Borrow<T> for SingleVector<T> {
    #[inline]
    fn borrow(&self) -> &T {
        &self.0
    }
}
impl<T> BorrowMut<T> for SingleVector<T> {
    #[inline]
    fn borrow_mut(&mut self) -> &mut T {
        &mut self.0
    }
}
impl<T> Borrow<[T]> for SingleVector<T> {
    #[inline]
    fn borrow(&self) -> &[T] {
        core::slice::from_ref(&self.0)
    }
}
impl<T> BorrowMut<[T]> for SingleVector<T> {
    #[inline]
    fn borrow_mut(&mut self) -> &mut [T] {
        core::slice::from_mut(&mut self.0)
    }
}

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

    #[inline]
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}
impl<T> DerefMut for SingleVector<T> {
    #[inline]
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}
// TODO: Add test.
unsafe impl<T: Initialize> Initialize for SingleVector<T> {
    type Item = <T as Initialize>::Item;

    #[inline]
    fn as_maybe_uninit_slice(&self) -> &[MaybeUninit<Self::Item>] {
        <T as Initialize>::as_maybe_uninit_slice(&self.0)
    }
    #[inline]
    unsafe fn as_maybe_uninit_slice_mut(&mut self) -> &mut [MaybeUninit<Self::Item>] {
        <T as Initialize>::as_maybe_uninit_slice_mut(&mut self.0)
    }
}
unsafe impl<T: Initialize> InitializeVectored for SingleVector<T> {
    type UninitVector = T;

    #[inline]
    fn as_maybe_uninit_vectors(&self) -> &[Self::UninitVector] {
        core::slice::from_ref(&self.0)
    }
    #[inline]
    unsafe fn as_maybe_uninit_vectors_mut(&mut self) -> &mut [Self::UninitVector] {
        core::slice::from_mut(&mut self.0)
    }
}

#[derive(Debug)]
#[repr(transparent)]
pub struct AsUninit<T>(pub T);

impl<T> Deref for AsUninit<T>
where
    T: Deref,
{
    type Target = <T as Deref>::Target;

    #[inline]
    fn deref(&self) -> &Self::Target {
        &*self.0
    }
}
impl<T> DerefMut for AsUninit<T>
where
    T: DerefMut,
{
    #[inline]
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut *self.0
    }
}

unsafe impl<T, Item> Initialize for AsUninit<T>
where
    T: Deref<Target = [Item]> + DerefMut + TrustedDeref,
{
    type Item = Item;

    #[inline]
    fn as_maybe_uninit_slice(&self) -> &[MaybeUninit<Item>] {
        let slice: &[Item] = &*self;
        crate::cast_init_to_uninit_slice(slice)
    }
    #[inline]
    unsafe fn as_maybe_uninit_slice_mut(&mut self) -> &mut [MaybeUninit<Item>] {
        let slice_mut: &mut [Item] = &mut *self;
        crate::cast_init_to_uninit_slice_mut(slice_mut)
    }
}