Skip to main content

aligned/
lib.rs

1//! A newtype with alignment of at least `A` bytes
2//!
3//! # Examples
4//!
5//! ```
6//! use std::mem;
7//!
8//! use aligned::{Aligned, A2, A4, A16};
9//!
10//! // Array aligned to a 2 byte boundary
11//! static X: Aligned<A2, [u8; 3]> = Aligned([0; 3]);
12//!
13//! // Array aligned to a 4 byte boundary
14//! static Y: Aligned<A4, [u8; 3]> = Aligned([0; 3]);
15//!
16//! // Unaligned array
17//! static Z: [u8; 3] = [0; 3];
18//!
19//! // You can allocate the aligned arrays on the stack too
20//! let w: Aligned<A16, _> = Aligned([0u8; 3]);
21//!
22//! assert_eq!(mem::align_of_val(&X), 2);
23//! assert_eq!(mem::align_of_val(&Y), 4);
24//! assert_eq!(mem::align_of_val(&Z), 1);
25//! assert_eq!(mem::align_of_val(&w), 16);
26//! ```
27
28#![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::{self},
38};
39
40use as_slice::{AsMutSlice, AsSlice};
41
42/// A marker trait for an alignment value.
43pub trait Alignment: Copy + sealed::Sealed {
44    /// The alignment in bytes.
45    const ALIGN: usize;
46}
47
48impl Alignment for A1 {
49    const ALIGN: usize = 1;
50}
51impl Alignment for A2 {
52    const ALIGN: usize = 2;
53}
54impl Alignment for A4 {
55    const ALIGN: usize = 4;
56}
57impl Alignment for A8 {
58    const ALIGN: usize = 8;
59}
60impl Alignment for A16 {
61    const ALIGN: usize = 16;
62}
63impl Alignment for A32 {
64    const ALIGN: usize = 32;
65}
66impl Alignment for A64 {
67    const ALIGN: usize = 64;
68}
69
70mod sealed {
71    pub trait Sealed {}
72
73    impl Sealed for super::A1 {}
74    impl Sealed for super::A2 {}
75    impl Sealed for super::A4 {}
76    impl Sealed for super::A8 {}
77    impl Sealed for super::A16 {}
78    impl Sealed for super::A32 {}
79    impl Sealed for super::A64 {}
80}
81
82/// 1-byte alignment
83#[derive(Clone, Copy)]
84#[repr(align(1))]
85pub struct A1;
86
87/// 2-byte alignment
88#[derive(Clone, Copy)]
89#[repr(align(2))]
90pub struct A2;
91
92/// 4-byte alignment
93#[derive(Clone, Copy)]
94#[repr(align(4))]
95pub struct A4;
96
97/// 8-byte alignment
98#[derive(Clone, Copy)]
99#[repr(align(8))]
100pub struct A8;
101
102/// 16-byte alignment
103#[derive(Clone, Copy)]
104#[repr(align(16))]
105pub struct A16;
106
107/// 32-byte alignment
108#[derive(Clone, Copy)]
109#[repr(align(32))]
110pub struct A32;
111
112/// 64-byte alignment
113#[derive(Clone, Copy)]
114#[repr(align(64))]
115pub struct A64;
116
117/// A newtype with alignment of at least `A` bytes
118#[repr(C)]
119pub struct Aligned<A, T>
120where
121    T: ?Sized,
122{
123    _alignment: [A; 0],
124    value: T,
125}
126
127/// Changes the alignment of `value` to be at least `A` bytes
128#[allow(non_snake_case)]
129pub const fn Aligned<A, T>(value: T) -> Aligned<A, T> {
130    Aligned {
131        _alignment: [],
132        value,
133    }
134}
135
136impl<A, T> ops::Deref for Aligned<A, T>
137where
138    A: Alignment,
139    T: ?Sized,
140{
141    type Target = T;
142
143    fn deref(&self) -> &T {
144        &self.value
145    }
146}
147
148impl<A, T> ops::DerefMut for Aligned<A, T>
149where
150    A: Alignment,
151    T: ?Sized,
152{
153    fn deref_mut(&mut self) -> &mut T {
154        &mut self.value
155    }
156}
157
158impl<A, T> Aligned<A, [T]>
159where
160    A: Alignment,
161{
162    fn is_index_aligned(index: usize) -> bool {
163        use core::mem::size_of;
164
165        (index * size_of::<T>()) % A::ALIGN == 0
166    }
167    fn check_start_index(index: usize) {
168        if !Self::is_index_aligned(index) {
169            panic!("Unaligned start index");
170        }
171    }
172}
173
174impl<A, T> ops::Index<ops::RangeFrom<usize>> for Aligned<A, [T]>
175where
176    A: Alignment,
177{
178    type Output = Aligned<A, [T]>;
179
180    fn index(&self, range: ops::RangeFrom<usize>) -> &Aligned<A, [T]> {
181        Self::check_start_index(range.start);
182        unsafe { &*(&self.value[range] as *const [T] as *const Aligned<A, [T]>) }
183    }
184}
185
186impl<A, T> ops::Index<ops::RangeTo<usize>> for Aligned<A, [T]>
187where
188    A: Alignment,
189{
190    type Output = Aligned<A, [T]>;
191
192    fn index(&self, range: ops::RangeTo<usize>) -> &Aligned<A, [T]> {
193        unsafe { &*(&self.value[range] as *const [T] as *const Aligned<A, [T]>) }
194    }
195}
196
197impl<A, T> ops::Index<ops::RangeToInclusive<usize>> for Aligned<A, [T]>
198where
199    A: Alignment,
200{
201    type Output = Aligned<A, [T]>;
202
203    fn index(&self, range: ops::RangeToInclusive<usize>) -> &Aligned<A, [T]> {
204        unsafe { &*(&self.value[range] as *const [T] as *const Aligned<A, [T]>) }
205    }
206}
207
208impl<A, T> ops::Index<ops::RangeInclusive<usize>> for Aligned<A, [T]>
209where
210    A: Alignment,
211{
212    type Output = Aligned<A, [T]>;
213
214    fn index(&self, range: ops::RangeInclusive<usize>) -> &Aligned<A, [T]> {
215        Self::check_start_index(*range.start());
216        unsafe { &*(&self.value[range] as *const [T] as *const Aligned<A, [T]>) }
217    }
218}
219
220impl<A, T> ops::Index<ops::Range<usize>> for Aligned<A, [T]>
221where
222    A: Alignment,
223{
224    type Output = Aligned<A, [T]>;
225
226    fn index(&self, range: ops::Range<usize>) -> &Aligned<A, [T]> {
227        Self::check_start_index(range.start);
228        unsafe { &*(&self.value[range] as *const [T] as *const Aligned<A, [T]>) }
229    }
230}
231
232impl<A, T> ops::Index<ops::RangeFull> for Aligned<A, [T]>
233where
234    A: Alignment,
235{
236    type Output = Aligned<A, [T]>;
237
238    fn index(&self, range: ops::RangeFull) -> &Aligned<A, [T]> {
239        unsafe { &*(&self.value[range] as *const [T] as *const Aligned<A, [T]>) }
240    }
241}
242
243impl<A, T> ops::IndexMut<ops::RangeFrom<usize>> for Aligned<A, [T]>
244where
245    A: Alignment,
246{
247    fn index_mut(&mut self, range: ops::RangeFrom<usize>) -> &mut Aligned<A, [T]> {
248        Self::check_start_index(range.start);
249        unsafe { &mut *(&mut self.value[range] as *mut [T] as *mut Aligned<A, [T]>) }
250    }
251}
252
253impl<A, T> ops::IndexMut<ops::RangeTo<usize>> for Aligned<A, [T]>
254where
255    A: Alignment,
256{
257    fn index_mut(&mut self, range: ops::RangeTo<usize>) -> &mut Aligned<A, [T]> {
258        unsafe { &mut *(&mut self.value[range] as *mut [T] as *mut Aligned<A, [T]>) }
259    }
260}
261
262impl<A, T> ops::IndexMut<ops::RangeToInclusive<usize>> for Aligned<A, [T]>
263where
264    A: Alignment,
265{
266    fn index_mut(&mut self, range: ops::RangeToInclusive<usize>) -> &mut Aligned<A, [T]> {
267        unsafe { &mut *(&mut self.value[range] as *mut [T] as *mut Aligned<A, [T]>) }
268    }
269}
270
271impl<A, T> ops::IndexMut<ops::RangeInclusive<usize>> for Aligned<A, [T]>
272where
273    A: Alignment,
274{
275    fn index_mut(&mut self, range: ops::RangeInclusive<usize>) -> &mut Aligned<A, [T]> {
276        Self::check_start_index(*range.start());
277        unsafe { &mut *(&mut self.value[range] as *mut [T] as *mut Aligned<A, [T]>) }
278    }
279}
280
281impl<A, T> ops::IndexMut<ops::Range<usize>> for Aligned<A, [T]>
282where
283    A: Alignment,
284{
285    fn index_mut(&mut self, range: ops::Range<usize>) -> &mut Aligned<A, [T]> {
286        Self::check_start_index(range.start);
287        unsafe { &mut *(&mut self.value[range] as *mut [T] as *mut Aligned<A, [T]>) }
288    }
289}
290
291impl<A, T> ops::IndexMut<ops::RangeFull> for Aligned<A, [T]>
292where
293    A: Alignment,
294{
295    fn index_mut(&mut self, range: ops::RangeFull) -> &mut Aligned<A, [T]> {
296        unsafe { &mut *(&mut self.value[range] as *mut [T] as *mut Aligned<A, [T]>) }
297    }
298}
299
300impl<A, T> AsSlice for Aligned<A, T>
301where
302    A: Alignment,
303    T: AsSlice,
304{
305    type Element = T::Element;
306
307    fn as_slice(&self) -> &[T::Element] {
308        T::as_slice(&**self)
309    }
310}
311
312impl<A, T> AsMutSlice for Aligned<A, T>
313where
314    A: Alignment,
315    T: AsMutSlice,
316{
317    fn as_mut_slice(&mut self) -> &mut [T::Element] {
318        T::as_mut_slice(&mut **self)
319    }
320}
321
322impl<A, T> Borrow<T> for Aligned<A, T>
323where
324    A: Alignment,
325{
326    fn borrow(&self) -> &T {
327        &self.value
328    }
329}
330
331impl<A, T> BorrowMut<T> for Aligned<A, T>
332where
333    A: Alignment,
334{
335    fn borrow_mut(&mut self) -> &mut T {
336        &mut self.value
337    }
338}
339
340impl<A, T> Borrow<[<Aligned<A, T> as AsSlice>::Element]> for Aligned<A, T>
341where
342    A: Alignment,
343    Aligned<A, T>: AsSlice,
344{
345    fn borrow(&self) -> &[<Aligned<A, T> as AsSlice>::Element] {
346        self.as_slice()
347    }
348}
349
350impl<A, T> BorrowMut<[<Aligned<A, T> as AsSlice>::Element]> for Aligned<A, T>
351where
352    A: Alignment,
353    Aligned<A, T>: AsMutSlice,
354{
355    fn borrow_mut(&mut self) -> &mut [<Aligned<A, T> as AsSlice>::Element] {
356        self.as_mut_slice()
357    }
358}
359
360impl<A, T> Clone for Aligned<A, T>
361where
362    A: Alignment,
363    T: Clone,
364{
365    fn clone(&self) -> Self {
366        Self {
367            _alignment: [],
368            value: self.value.clone(),
369        }
370    }
371}
372
373impl<A, T> Copy for Aligned<A, T>
374where
375    A: Alignment,
376    T: Copy,
377{
378}
379
380impl<A, T> Default for Aligned<A, T>
381where
382    A: Alignment,
383    T: Default,
384{
385    fn default() -> Self {
386        Self {
387            _alignment: [],
388            value: Default::default(),
389        }
390    }
391}
392
393impl<A, T> Debug for Aligned<A, T>
394where
395    A: Alignment,
396    T: Debug,
397{
398    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
399        self.value.fmt(f)
400    }
401}
402
403impl<A, T> Display for Aligned<A, T>
404where
405    A: Alignment,
406    T: Display,
407{
408    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
409        self.value.fmt(f)
410    }
411}
412
413impl<A, T> PartialEq for Aligned<A, T>
414where
415    A: Alignment,
416    T: PartialEq,
417{
418    fn eq(&self, other: &Self) -> bool {
419        self.value == other.value
420    }
421}
422
423impl<A, T> Eq for Aligned<A, T>
424where
425    A: Alignment,
426    T: Eq,
427{
428}
429
430impl<A, T> Hash for Aligned<A, T>
431where
432    A: Alignment,
433    T: Hash,
434{
435    fn hash<H: Hasher>(&self, state: &mut H) {
436        self.value.hash(state);
437    }
438}
439
440impl<A, T> Ord for Aligned<A, T>
441where
442    A: Alignment,
443    T: Ord,
444{
445    fn cmp(&self, other: &Self) -> Ordering {
446        self.value.cmp(&other.value)
447    }
448}
449
450impl<A, T> PartialOrd for Aligned<A, T>
451where
452    A: Alignment,
453    T: PartialOrd,
454{
455    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
456        self.value.partial_cmp(&other.value)
457    }
458}
459
460#[test]
461fn sanity() {
462    use core::mem;
463
464    let a: Aligned<A1, _> = Aligned([0u8; 3]);
465    let x: Aligned<A2, _> = Aligned([0u8; 3]);
466    let y: Aligned<A4, _> = Aligned([0u8; 3]);
467    let z: Aligned<A8, _> = Aligned([0u8; 3]);
468    let w: Aligned<A16, _> = Aligned([0u8; 3]);
469
470    // check alignment
471    assert_eq!(mem::align_of_val(&a), 1);
472    assert_eq!(mem::align_of_val(&x), 2);
473    assert_eq!(mem::align_of_val(&y), 4);
474    assert_eq!(mem::align_of_val(&z), 8);
475    assert_eq!(mem::align_of_val(&w), 16);
476
477    assert!(a.as_ptr() as usize % 1 == 0);
478    assert!(x.as_ptr() as usize % 2 == 0);
479    assert!(y.as_ptr() as usize % 4 == 0);
480    assert!(z.as_ptr() as usize % 8 == 0);
481    assert!(w.as_ptr() as usize % 16 == 0);
482
483    // test `deref`
484    assert_eq!(a.len(), 3);
485    assert_eq!(x.len(), 3);
486    assert_eq!(y.len(), 3);
487    assert_eq!(z.len(), 3);
488    assert_eq!(w.len(), 3);
489
490    // alignment should be preserved after slicing
491    let a: &Aligned<_, [_]> = &a;
492    let x: &Aligned<_, [_]> = &x;
493    let y: &Aligned<_, [_]> = &y;
494    let z: &Aligned<_, [_]> = &z;
495    let w: &Aligned<_, [_]> = &w;
496
497    let a: &Aligned<_, _> = &a[..2];
498    let x: &Aligned<_, _> = &x[..2];
499    let y: &Aligned<_, _> = &y[..2];
500    let z: &Aligned<_, _> = &z[..2];
501    let w: &Aligned<_, _> = &w[..2];
502
503    assert!(a.as_ptr() as usize % 1 == 0);
504    assert!(x.as_ptr() as usize % 2 == 0);
505    assert!(y.as_ptr() as usize % 4 == 0);
506    assert!(z.as_ptr() as usize % 8 == 0);
507    assert!(w.as_ptr() as usize % 16 == 0);
508
509    // alignment should be preserved after boxing
510    let a: Box<Aligned<A1, [u8]>> = Box::new(Aligned([0u8; 3]));
511    let x: Box<Aligned<A2, [u8]>> = Box::new(Aligned([0u8; 3]));
512    let y: Box<Aligned<A4, [u8]>> = Box::new(Aligned([0u8; 3]));
513    let z: Box<Aligned<A8, [u8]>> = Box::new(Aligned([0u8; 3]));
514    let w: Box<Aligned<A16, [u8]>> = Box::new(Aligned([0u8; 3]));
515
516    assert_eq!(mem::align_of_val(&*a), 1);
517    assert_eq!(mem::align_of_val(&*x), 2);
518    assert_eq!(mem::align_of_val(&*y), 4);
519    assert_eq!(mem::align_of_val(&*z), 8);
520    assert_eq!(mem::align_of_val(&*w), 16);
521
522    // test coercions
523    let x: Aligned<A2, _> = Aligned([0u8; 3]);
524    let y: &Aligned<A2, [u8]> = &x;
525    let _: &[u8] = y;
526}
527
528#[test]
529fn test_range_to() {
530    let a: &Aligned<A2, [u8]> = &Aligned::<A2, _>([0, 1, 2, 3]);
531    assert_eq!((&a[..0]).as_slice(), &[],);
532    assert_eq!((&a[..1]).as_slice(), &[0],);
533    assert_eq!((&a[..2]).as_slice(), &[0, 1],);
534    assert_eq!((&a[..3]).as_slice(), &[0, 1, 2],);
535    assert_eq!((&a[..4]).as_slice(), &[0, 1, 2, 3],);
536}
537
538#[test]
539fn test_range_to_mut() {
540    let a: &mut Aligned<A2, [u8]> = &mut Aligned::<A2, _>([0, 1, 2, 3]);
541    assert_eq!((&mut a[..0]).as_slice(), &[],);
542    assert_eq!((&mut a[..1]).as_slice(), &[0],);
543    assert_eq!((&mut a[..2]).as_slice(), &[0, 1],);
544    assert_eq!((&mut a[..3]).as_slice(), &[0, 1, 2],);
545    assert_eq!((&mut a[..4]).as_slice(), &[0, 1, 2, 3],);
546}
547
548#[test]
549fn test_range_to_inclusive() {
550    let a: &Aligned<A2, [u8]> = &Aligned::<A2, _>([0, 1, 2, 3]);
551    assert_eq!((&a[..=0]).as_slice(), &[0],);
552    assert_eq!((&a[..=1]).as_slice(), &[0, 1],);
553    assert_eq!((&a[..=2]).as_slice(), &[0, 1, 2],);
554    assert_eq!((&a[..=3]).as_slice(), &[0, 1, 2, 3],);
555}
556
557#[test]
558fn test_range_to_inclusive_mut() {
559    let a: &mut Aligned<A2, [u8]> = &mut Aligned::<A2, _>([0, 1, 2, 3]);
560    assert_eq!((&mut a[..=0]).as_slice(), &[0],);
561    assert_eq!((&mut a[..=1]).as_slice(), &[0, 1],);
562    assert_eq!((&mut a[..=2]).as_slice(), &[0, 1, 2],);
563    assert_eq!((&mut a[..=3]).as_slice(), &[0, 1, 2, 3],);
564}
565
566#[test]
567fn test_range_full() {
568    let a: &Aligned<A2, [u8]> = &Aligned::<A2, _>([0, 1, 2, 3]);
569    assert_eq!((&a[..]).as_slice(), &[0, 1, 2, 3],);
570}
571
572#[test]
573fn test_range_full_mut() {
574    let a: &Aligned<A2, [u8]> = &Aligned::<A2, _>([0, 1, 2, 3]);
575    assert_eq!((&a[..]).as_slice(), &[0, 1, 2, 3],);
576}
577
578#[test]
579fn test_range_from() {
580    let a: &Aligned<A2, [u8]> = &Aligned::<A2, _>([0, 1, 2, 3]);
581    assert_eq!((&a[0..]).as_slice(), &[0, 1, 2, 3],);
582    assert_eq!((&a[2..]).as_slice(), &[2, 3],);
583    assert_eq!((&a[4..]).as_slice(), &[],);
584
585    let a: &Aligned<A2, [u8]> = &Aligned::<A2, _>([0, 1, 2]);
586    assert_eq!((&a[0..]).as_slice(), &[0, 1, 2],);
587    assert_eq!((&a[2..]).as_slice(), &[2],);
588
589    let a: &Aligned<A4, [u8]> = &Aligned::<A4, _>([0, 1, 2, 3, 4, 5, 6, 7]);
590    assert_eq!((&a[0..]).as_slice(), &[0, 1, 2, 3, 4, 5, 6, 7],);
591    assert_eq!((&a[4..]).as_slice(), &[4, 5, 6, 7],);
592    assert_eq!((&a[8..]).as_slice(), &[],);
593
594    let a: &Aligned<A4, [u8]> = &Aligned::<A4, _>([0, 1, 2, 3, 4, 5, 6]);
595    assert_eq!((&a[0..]).as_slice(), &[0, 1, 2, 3, 4, 5, 6],);
596    assert_eq!((&a[4..]).as_slice(), &[4, 5, 6],);
597
598    let a: &Aligned<A8, [u8]> =
599        &Aligned::<A8, _>([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
600    assert_eq!(
601        (&a[0..]).as_slice(),
602        &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
603    );
604    assert_eq!((&a[8..]).as_slice(), &[8, 9, 10, 11, 12, 13, 14, 15],);
605    assert_eq!((&a[16..]).as_slice(), &[],);
606
607    let a: &Aligned<A8, [u8]> =
608        &Aligned::<A8, _>([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]);
609    assert_eq!(
610        (&a[0..]).as_slice(),
611        &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14],
612    );
613    assert_eq!((&a[8..]).as_slice(), &[8, 9, 10, 11, 12, 13, 14],);
614
615    let a: &Aligned<A16, [u8]> = &Aligned::<A16, _>([
616        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
617        25, 26, 27, 28, 29, 30, 31,
618    ]);
619    assert_eq!(
620        (&a[0..]).as_slice(),
621        &[
622            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
623            24, 25, 26, 27, 28, 29, 30, 31
624        ],
625    );
626    assert_eq!(
627        (&a[16..]).as_slice(),
628        &[16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31],
629    );
630    assert_eq!((&a[32..]).as_slice(), &[],);
631
632    let a: &Aligned<A16, [u8]> = &Aligned::<A16, _>([
633        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
634        25, 26, 27, 28, 29, 30,
635    ]);
636    assert_eq!(
637        (&a[0..]).as_slice(),
638        &[
639            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
640            24, 25, 26, 27, 28, 29, 30
641        ],
642    );
643    assert_eq!(
644        (&a[16..]).as_slice(),
645        &[16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30],
646    );
647
648    let a: &Aligned<A32, [u8]> = &Aligned::<A32, _>([
649        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
650        25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
651        48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
652    ]);
653    assert_eq!(
654        (&a[0..]).as_slice(),
655        &[
656            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
657            24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
658            46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63
659        ]
660    );
661    assert_eq!(
662        (&a[32..]).as_slice(),
663        &[
664            32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
665            54, 55, 56, 57, 58, 59, 60, 61, 62, 63
666        ]
667    );
668    assert_eq!((&a[64..]).as_slice(), &[],);
669
670    let a: &Aligned<A32, [u8]> = &Aligned::<A32, _>([
671        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
672        25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
673        48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
674    ]);
675    assert_eq!(
676        (&a[0..]).as_slice(),
677        &[
678            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
679            24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
680            46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62
681        ]
682    );
683    assert_eq!(
684        (&a[32..]).as_slice(),
685        &[
686            32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
687            54, 55, 56, 57, 58, 59, 60, 61, 62
688        ]
689    );
690
691    let a: &Aligned<A64, [u8]> = &Aligned::<A64, _>([
692        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
693        25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
694        48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
695        71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
696        94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
697        113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
698    ]);
699    assert_eq!(
700        (&a[0..]).as_slice(),
701        &[
702            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
703            24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
704            46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
705            68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
706            90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
707            109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
708            126, 127
709        ]
710    );
711    assert_eq!(
712        (&a[64..]).as_slice(),
713        &[
714            64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,
715            86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
716            106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122,
717            123, 124, 125, 126, 127
718        ]
719    );
720    assert_eq!((&a[128..]).as_slice(), &[]);
721
722    let a: &Aligned<A64, [u8]> = &Aligned::<A64, _>([
723        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
724        25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
725        48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
726        71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
727        94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
728        113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
729    ]);
730    assert_eq!(
731        (&a[0..]).as_slice(),
732        &[
733            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
734            24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
735            46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
736            68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
737            90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
738            109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
739            126
740        ]
741    );
742    assert_eq!(
743        (&a[64..]).as_slice(),
744        &[
745            64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,
746            86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
747            106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122,
748            123, 124, 125, 126
749        ]
750    );
751}
752
753#[test]
754#[should_panic(expected = "Unaligned start index")]
755fn test_range_from_a2_invalid_alignment() {
756    let a: &Aligned<A2, [u8]> = &Aligned::<A2, _>([0u8; 4]);
757    let _ = &a[1..];
758}
759
760#[test]
761#[should_panic(expected = "Unaligned start index")]
762fn test_range_from_a4_invalid_alignment() {
763    let a: &Aligned<A4, [u8]> = &Aligned::<A4, _>([0u8; 8]);
764    let _ = &a[6..];
765}
766
767#[test]
768fn test_range_from_mut() {
769    let a: &mut Aligned<A2, [u8]> = &mut Aligned::<A2, _>([0, 1, 2, 3]);
770    assert_eq!((&mut a[0..]).as_slice(), &[0, 1, 2, 3],);
771    assert_eq!((&mut a[2..]).as_slice(), &[2, 3],);
772    assert_eq!((&mut a[4..]).as_slice(), &[],);
773
774    let a: &mut Aligned<A2, [u8]> = &mut Aligned::<A2, _>([0, 1, 2]);
775    assert_eq!((&mut a[0..]).as_slice(), &[0, 1, 2],);
776    assert_eq!((&mut a[2..]).as_slice(), &[2],);
777}
778
779#[test]
780#[should_panic(expected = "Unaligned start index")]
781fn test_range_from_mut_invalid_argument() {
782    let a: &mut Aligned<A2, [u8]> = &mut Aligned::<A2, _>([0u8; 4]);
783    let _ = &mut a[1..];
784}
785
786#[test]
787fn test_range() {
788    let a: &Aligned<A2, [u8]> = &Aligned::<A2, _>([0, 1, 2, 3]);
789    assert_eq!((&a[0..0]).as_slice(), &[],);
790    assert_eq!((&a[0..1]).as_slice(), &[0],);
791    assert_eq!((&a[0..2]).as_slice(), &[0, 1],);
792    assert_eq!((&a[0..3]).as_slice(), &[0, 1, 2],);
793    assert_eq!((&a[0..4]).as_slice(), &[0, 1, 2, 3],);
794    assert_eq!((&a[2..2]).as_slice(), &[],);
795    assert_eq!((&a[2..3]).as_slice(), &[2],);
796    assert_eq!((&a[2..4]).as_slice(), &[2, 3],);
797    assert_eq!((&a[4..4]).as_slice(), &[],);
798}
799
800#[test]
801#[should_panic(expected = "Unaligned start index")]
802fn test_range_invalid_alignment() {
803    let a: &Aligned<A2, [u8]> = &Aligned::<A2, _>([0u8; 4]);
804    let _ = &a[1..2];
805}
806
807#[test]
808fn test_range_mut() {
809    let a: &mut Aligned<A2, [u8]> = &mut Aligned::<A2, _>([0, 1, 2, 3]);
810    assert_eq!((&mut a[0..0]).as_slice(), &[],);
811    assert_eq!((&mut a[0..1]).as_slice(), &[0],);
812    assert_eq!((&mut a[0..2]).as_slice(), &[0, 1],);
813    assert_eq!((&mut a[0..3]).as_slice(), &[0, 1, 2],);
814    assert_eq!((&mut a[0..4]).as_slice(), &[0, 1, 2, 3],);
815    assert_eq!((&mut a[2..2]).as_slice(), &[],);
816    assert_eq!((&mut a[2..3]).as_slice(), &[2],);
817    assert_eq!((&mut a[2..4]).as_slice(), &[2, 3],);
818    assert_eq!((&mut a[4..4]).as_slice(), &[],);
819}
820
821#[test]
822#[should_panic(expected = "Unaligned start index")]
823fn test_range_mut_invalid_alignment() {
824    let a: &mut Aligned<A2, [u8]> = &mut Aligned::<A2, _>([0u8; 4]);
825    let _ = &mut a[1..2];
826}
827
828#[test]
829fn test_range_inclusive() {
830    let a: &Aligned<A2, [u8]> = &Aligned::<A2, _>([0, 1, 2, 3]);
831    assert_eq!((&a[0..=0]).as_slice(), &[0],);
832    assert_eq!((&a[0..=1]).as_slice(), &[0, 1],);
833    assert_eq!((&a[0..=2]).as_slice(), &[0, 1, 2],);
834    assert_eq!((&a[0..=3]).as_slice(), &[0, 1, 2, 3],);
835    assert_eq!((&a[2..=2]).as_slice(), &[2],);
836    assert_eq!((&a[2..=3]).as_slice(), &[2, 3],);
837}
838
839#[test]
840#[should_panic(expected = "Unaligned start index")]
841fn test_range_inclusive_invalid_alignment() {
842    let a: &Aligned<A2, [u8]> = &Aligned::<A2, _>([0u8; 4]);
843    let _ = &a[1..=2];
844}
845
846#[test]
847fn test_range_inclusive_mut() {
848    let a: &mut Aligned<A2, [u8]> = &mut Aligned::<A2, _>([0, 1, 2, 3]);
849    assert_eq!((&mut a[0..=0]).as_slice(), &[0],);
850    assert_eq!((&mut a[0..=1]).as_slice(), &[0, 1],);
851    assert_eq!((&mut a[0..=2]).as_slice(), &[0, 1, 2],);
852    assert_eq!((&mut a[0..=3]).as_slice(), &[0, 1, 2, 3],);
853    assert_eq!((&mut a[2..=2]).as_slice(), &[2],);
854    assert_eq!((&mut a[2..=3]).as_slice(), &[2, 3],);
855}
856
857#[test]
858#[should_panic(expected = "Unaligned start index")]
859fn test_range_inclusive_mut_invalid_alignment() {
860    let a: &mut Aligned<A2, [u8]> = &mut Aligned::<A2, _>([0u8; 4]);
861    let _ = &mut a[1..=2];
862}
863
864#[test]
865#[should_panic(expected = "out of range")]
866fn test_range_from_out_of_bounds() {
867    let a: &Aligned<A2, [u8]> = &Aligned::<A2, _>([0u8; 4]);
868    let _ = &a[6..];
869}