dungeon_cell/align/
unaligned.rs1use core::ptr::{addr_of, addr_of_mut, read_unaligned, write_unaligned};
2
3use crate::bound::Dynamic;
4use crate::marker_traits::IsBound;
5use crate::vtable::{ConstVTableOf, VTable, VTableOf, VTableSubset};
6
7#[repr(C, packed)]
13pub struct Unaligned<T> {
14 value: T,
15}
16
17impl<T> Unaligned<T> {
18 pub const fn new(value: T) -> Self {
22 Self { value }
23 }
24
25 pub fn into_inner(self) -> T {
29 self.value
30 }
31
32 pub fn replace(&mut self, value: T) -> T {
34 let old = unsafe { read_unaligned(self.as_ptr()) };
37
38 unsafe { write_unaligned(self.as_mut_ptr(), value) };
41
42 old
43 }
44
45 pub fn as_ptr(&self) -> *const T {
51 addr_of!(self.value)
52 }
53
54 pub fn as_mut_ptr(&mut self) -> *mut T {
60 addr_of_mut!(self.value)
61 }
62}
63
64impl<T: Copy> Copy for Unaligned<T> {}
65
66impl<T: Copy> Clone for Unaligned<T> {
67 #[inline]
68 fn clone(&self) -> Self {
69 *self
70 }
71}
72
73unsafe impl<T: VTable> VTable for Unaligned<&T> {
75 type Bounds = T::Bounds;
76
77 type Id = T::Id;
78
79 fn descriptor(&self) -> &crate::vtable::Descriptor<Self::Id> {
80 T::descriptor(self.into_inner())
81 }
82
83 fn bound_impl(&self) -> &crate::vtable::BoundsImpl<Self::Bounds> {
84 T::bound_impl(self.into_inner())
85 }
86}
87
88unsafe impl<'a, T: VTable, Bnew: IsBound> VTableSubset<Bnew>
90 for Unaligned<&'a T>
91where
92 &'a T: VTableSubset<Bnew>,
93 <&'a T as VTableSubset<Bnew>>::Subset: Copy,
94 Unaligned<<&'a T as VTableSubset<Bnew>>::Subset>: VTable<Bounds = Bnew>,
95{
96 type Subset = Unaligned<<&'a T as VTableSubset<Bnew>>::Subset>;
97
98 fn into_subset(self) -> Self::Subset {
99 Unaligned::new(self.into_inner().into_subset())
100 }
101}
102
103unsafe impl<'a, T: VTable, U: Dynamic<T::Bounds>> VTableOf<U>
105 for Unaligned<&'a T>
106where
107 &'a T: VTableOf<U, Bounds = T::Bounds>,
108{
109 fn instance() -> Self {
110 Unaligned::new(<&T>::instance())
111 }
112}
113
114unsafe impl<'a, T: VTable, U: Dynamic<T::Bounds>> ConstVTableOf<U>
116 for Unaligned<&'a T>
117where
118 &'a T: ConstVTableOf<U, Bounds = T::Bounds>,
119{
120 const INSTANCE: Self = Unaligned::new(<&T>::INSTANCE);
121}