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
#![feature(const_maybe_uninit_as_mut_ptr)]
#![feature(const_mut_refs)]
#![feature(const_ptr_write)]
#![feature(const_trait_impl)]
#![feature(effects)]
#![feature(ptr_metadata)]
#![feature(unsize)]

#![no_std]

use const_default::ConstDefault;
use core::borrow::{Borrow, BorrowMut};
use core::fmt::{self, Debug, Display, Formatter};
use core::marker::{PhantomData, Unsize};
use core::mem::{ManuallyDrop, MaybeUninit, align_of, size_of};
use core::ops::{Deref, DerefMut};
use core::ptr::{self, Pointee, null};

/// # Safety
///
/// This trait can be implemented only through unconditional delegating to another implementation.
#[const_trait]
pub unsafe trait Buf: ConstDefault {
    fn as_ptr(&self) -> *const u8;

    fn as_mut_ptr(&mut self) -> *mut u8;

    fn align() -> usize;

    fn len() -> usize;
}

pub struct BufFor<T>(MaybeUninit<T>);

impl<T> ConstDefault for BufFor<T> {
    const DEFAULT: Self = BufFor(MaybeUninit::uninit());
}

unsafe impl<T> const Buf for BufFor<T> {
    fn as_ptr(&self) -> *const u8 { self.0.as_ptr() as _ }

    fn as_mut_ptr(&mut self) -> *mut u8 { self.0.as_mut_ptr() as _ }

    fn align() -> usize { align_of::<T>() }

    fn len() -> usize { size_of::<T>() }
}

#[repr(C)]
pub union AnyOf2<T1, T2> {
    _a: ManuallyDrop<T1>,
    _b: ManuallyDrop<T2>,
}

pub struct ArrayBox<'a, T: ?Sized + 'a, B: Buf> {
    buf: B,
    metadata: <T as Pointee>::Metadata,
    phantom: PhantomData<&'a T>,
}

impl<'a, T: ?Sized + 'a, B: Buf> Drop for ArrayBox<'a, T, B> {
    fn drop(&mut self) {
        unsafe { ptr::drop_in_place(self.as_mut_ptr()) };
    }
}

impl<'a, T: ?Sized + 'a, B: Buf> ArrayBox<'a, T, B> {
    pub const fn new<S: Unsize<T>>(source: S) -> Self where B: ~const Buf + ConstDefault {
        assert!(B::align() >= align_of::<S>());
        assert!(B::len() >= size_of::<S>());
        let source_null_ptr: *const T = null::<S>();
        let metadata = source_null_ptr.to_raw_parts().1;
        let mut res = ArrayBox { buf: B::DEFAULT, metadata, phantom: PhantomData };
        unsafe { ptr::write(res.buf.as_mut_ptr() as *mut S, source) };
        res
    }

    pub fn as_ptr(&self) -> *const T {
        let metadata = self.metadata;
        ptr::from_raw_parts(self.buf.as_ptr() as *const (), metadata)
    }

    pub fn as_mut_ptr(&mut self) -> *mut T {
        let metadata = self.metadata;
        ptr::from_raw_parts_mut(self.buf.as_mut_ptr() as *mut (), metadata)
    }
}

impl<'a, T: ?Sized + 'a, B: Buf> AsRef<T> for ArrayBox<'a, T, B> {
    fn as_ref(&self) -> &T {
        unsafe { &*self.as_ptr() }
    }
}

impl<'a, T: ?Sized + 'a, B: Buf> AsMut<T> for ArrayBox<'a, T, B> {
    fn as_mut(&mut self) -> &mut T {
        unsafe { &mut *self.as_mut_ptr() }
    }
}
impl<'a, T: ?Sized + 'a, B: Buf> Borrow<T> for ArrayBox<'a, T, B> {
    fn borrow(&self) -> &T { self.as_ref() }
}

impl<'a, T: ?Sized + 'a, B: Buf> BorrowMut<T> for ArrayBox<'a, T, B> {
    fn borrow_mut(&mut self) -> &mut T { self.as_mut() }
}

impl<'a, T: ?Sized + 'a, B: Buf> Deref for ArrayBox<'a, T, B> {
    type Target = T;

    fn deref(&self) -> &T { self.as_ref() }
}

impl<'a, T: ?Sized + 'a, B: Buf> DerefMut for ArrayBox<'a, T, B> {
    fn deref_mut(&mut self) -> &mut T { self.as_mut() }
}

impl<'a, T: Debug + ?Sized + 'a, B: Buf> Debug for ArrayBox<'a, T, B> {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        self.as_ref().fmt(f)
    }
}

impl<'a, T: Display + ?Sized + 'a, B: Buf> Display for ArrayBox<'a, T, B> {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        self.as_ref().fmt(f)
    }
}