1#![deny(missing_docs)]
29#![deny(warnings)]
30#![cfg_attr(not(test), no_std)]
31
32use core::{
33 borrow::{Borrow, BorrowMut},
34 cmp::Ordering,
35 fmt::{Debug, Display},
36 hash::{Hash, Hasher},
37 ops,
38};
39
40use as_slice::{AsMutSlice, AsSlice};
41
42pub trait Alignment: Copy + sealed::Sealed {}
44
45impl Alignment for A1 {}
46impl Alignment for A2 {}
47impl Alignment for A4 {}
48impl Alignment for A8 {}
49impl Alignment for A16 {}
50impl Alignment for A32 {}
51impl Alignment for A64 {}
52
53mod sealed {
54 pub trait Sealed {}
55
56 impl Sealed for super::A1 {}
57 impl Sealed for super::A2 {}
58 impl Sealed for super::A4 {}
59 impl Sealed for super::A8 {}
60 impl Sealed for super::A16 {}
61 impl Sealed for super::A32 {}
62 impl Sealed for super::A64 {}
63}
64
65#[derive(Clone, Copy)]
67#[repr(align(1))]
68pub struct A1;
69
70#[derive(Clone, Copy)]
72#[repr(align(2))]
73pub struct A2;
74
75#[derive(Clone, Copy)]
77#[repr(align(4))]
78pub struct A4;
79
80#[derive(Clone, Copy)]
82#[repr(align(8))]
83pub struct A8;
84
85#[derive(Clone, Copy)]
87#[repr(align(16))]
88pub struct A16;
89
90#[derive(Clone, Copy)]
92#[repr(align(32))]
93pub struct A32;
94
95#[derive(Clone, Copy)]
97#[repr(align(64))]
98pub struct A64;
99
100#[repr(C)]
102pub struct Aligned<A, T>
103where
104 T: ?Sized,
105{
106 _alignment: [A; 0],
107 value: T,
108}
109
110#[allow(non_snake_case)]
112pub const fn Aligned<A, T>(value: T) -> Aligned<A, T> {
113 Aligned {
114 _alignment: [],
115 value,
116 }
117}
118
119impl<A, T> ops::Deref for Aligned<A, T>
120where
121 A: Alignment,
122 T: ?Sized,
123{
124 type Target = T;
125
126 fn deref(&self) -> &T {
127 &self.value
128 }
129}
130
131impl<A, T> ops::DerefMut for Aligned<A, T>
132where
133 A: Alignment,
134 T: ?Sized,
135{
136 fn deref_mut(&mut self) -> &mut T {
137 &mut self.value
138 }
139}
140
141impl<A, T> ops::Index<ops::RangeTo<usize>> for Aligned<A, [T]>
142where
143 A: Alignment,
144{
145 type Output = Aligned<A, [T]>;
146
147 fn index(&self, range: ops::RangeTo<usize>) -> &Aligned<A, [T]> {
148 unsafe { &*(&self.value[range] as *const [T] as *const Aligned<A, [T]>) }
149 }
150}
151
152impl<A, T> AsSlice for Aligned<A, T>
153where
154 A: Alignment,
155 T: AsSlice,
156{
157 type Element = T::Element;
158
159 fn as_slice(&self) -> &[T::Element] {
160 T::as_slice(&**self)
161 }
162}
163
164impl<A, T> AsMutSlice for Aligned<A, T>
165where
166 A: Alignment,
167 T: AsMutSlice,
168{
169 fn as_mut_slice(&mut self) -> &mut [T::Element] {
170 T::as_mut_slice(&mut **self)
171 }
172}
173
174impl<A, T> Borrow<T> for Aligned<A, T>
175where
176 A: Alignment,
177{
178 fn borrow(&self) -> &T {
179 &self.value
180 }
181}
182
183impl<A, T> BorrowMut<T> for Aligned<A, T>
184where
185 A: Alignment,
186{
187 fn borrow_mut(&mut self) -> &mut T {
188 &mut self.value
189 }
190}
191
192impl<A, T> Borrow<[<Aligned<A, T> as AsSlice>::Element]> for Aligned<A, T>
193where
194 A: Alignment,
195 Aligned<A, T>: AsSlice,
196{
197 fn borrow(&self) -> &[<Aligned<A, T> as AsSlice>::Element] {
198 self.as_slice()
199 }
200}
201
202impl<A, T> BorrowMut<[<Aligned<A, T> as AsSlice>::Element]> for Aligned<A, T>
203where
204 A: Alignment,
205 Aligned<A, T>: AsMutSlice,
206{
207 fn borrow_mut(&mut self) -> &mut [<Aligned<A, T> as AsSlice>::Element] {
208 self.as_mut_slice()
209 }
210}
211
212impl<A, T> Clone for Aligned<A, T>
213where
214 A: Alignment,
215 T: Clone,
216{
217 fn clone(&self) -> Self {
218 Self {
219 _alignment: [],
220 value: self.value.clone(),
221 }
222 }
223}
224
225impl<A, T> Copy for Aligned<A, T>
226where
227 A: Alignment,
228 T: Copy,
229{
230}
231
232impl<A, T> Default for Aligned<A, T>
233where
234 A: Alignment,
235 T: Default,
236{
237 fn default() -> Self {
238 Self {
239 _alignment: [],
240 value: Default::default(),
241 }
242 }
243}
244
245impl<A, T> Debug for Aligned<A, T>
246where
247 A: Alignment,
248 T: Debug,
249{
250 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
251 self.value.fmt(f)
252 }
253}
254
255impl<A, T> Display for Aligned<A, T>
256where
257 A: Alignment,
258 T: Display,
259{
260 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
261 self.value.fmt(f)
262 }
263}
264
265impl<A, T> PartialEq for Aligned<A, T>
266where
267 A: Alignment,
268 T: PartialEq,
269{
270 fn eq(&self, other: &Self) -> bool {
271 self.value == other.value
272 }
273}
274
275impl<A, T> Eq for Aligned<A, T>
276where
277 A: Alignment,
278 T: Eq,
279{
280}
281
282impl<A, T> Hash for Aligned<A, T>
283where
284 A: Alignment,
285 T: Hash,
286{
287 fn hash<H: Hasher>(&self, state: &mut H) {
288 self.value.hash(state);
289 }
290}
291
292impl<A, T> Ord for Aligned<A, T>
293where
294 A: Alignment,
295 T: Ord,
296{
297 fn cmp(&self, other: &Self) -> Ordering {
298 self.value.cmp(&other.value)
299 }
300}
301
302impl<A, T> PartialOrd for Aligned<A, T>
303where
304 A: Alignment,
305 T: PartialOrd,
306{
307 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
308 self.value.partial_cmp(&other.value)
309 }
310}
311
312#[test]
313fn sanity() {
314 use core::mem;
315
316 let a: Aligned<A1, _> = Aligned([0u8; 3]);
317 let x: Aligned<A2, _> = Aligned([0u8; 3]);
318 let y: Aligned<A4, _> = Aligned([0u8; 3]);
319 let z: Aligned<A8, _> = Aligned([0u8; 3]);
320 let w: Aligned<A16, _> = Aligned([0u8; 3]);
321
322 assert_eq!(mem::align_of_val(&a), 1);
324 assert_eq!(mem::align_of_val(&x), 2);
325 assert_eq!(mem::align_of_val(&y), 4);
326 assert_eq!(mem::align_of_val(&z), 8);
327 assert_eq!(mem::align_of_val(&w), 16);
328
329 assert!(a.as_ptr() as usize % 1 == 0);
330 assert!(x.as_ptr() as usize % 2 == 0);
331 assert!(y.as_ptr() as usize % 4 == 0);
332 assert!(z.as_ptr() as usize % 8 == 0);
333 assert!(w.as_ptr() as usize % 16 == 0);
334
335 assert_eq!(a.len(), 3);
337 assert_eq!(x.len(), 3);
338 assert_eq!(y.len(), 3);
339 assert_eq!(z.len(), 3);
340 assert_eq!(w.len(), 3);
341
342 let a: &Aligned<_, [_]> = &a;
344 let x: &Aligned<_, [_]> = &x;
345 let y: &Aligned<_, [_]> = &y;
346 let z: &Aligned<_, [_]> = &z;
347 let w: &Aligned<_, [_]> = &w;
348
349 let a: &Aligned<_, _> = &a[..2];
350 let x: &Aligned<_, _> = &x[..2];
351 let y: &Aligned<_, _> = &y[..2];
352 let z: &Aligned<_, _> = &z[..2];
353 let w: &Aligned<_, _> = &w[..2];
354
355 assert!(a.as_ptr() as usize % 1 == 0);
356 assert!(x.as_ptr() as usize % 2 == 0);
357 assert!(y.as_ptr() as usize % 4 == 0);
358 assert!(z.as_ptr() as usize % 8 == 0);
359 assert!(w.as_ptr() as usize % 16 == 0);
360
361 let a: Box<Aligned<A1, [u8]>> = Box::new(Aligned([0u8; 3]));
363 let x: Box<Aligned<A2, [u8]>> = Box::new(Aligned([0u8; 3]));
364 let y: Box<Aligned<A4, [u8]>> = Box::new(Aligned([0u8; 3]));
365 let z: Box<Aligned<A8, [u8]>> = Box::new(Aligned([0u8; 3]));
366 let w: Box<Aligned<A16, [u8]>> = Box::new(Aligned([0u8; 3]));
367
368 assert_eq!(mem::align_of_val(&*a), 1);
369 assert_eq!(mem::align_of_val(&*x), 2);
370 assert_eq!(mem::align_of_val(&*y), 4);
371 assert_eq!(mem::align_of_val(&*z), 8);
372 assert_eq!(mem::align_of_val(&*w), 16);
373
374 let x: Aligned<A2, _> = Aligned([0u8; 3]);
376 let y: &Aligned<A2, [u8]> = &x;
377 let _: &[u8] = y;
378}