/rust/registry/src/index.crates.io-1949cf8c6b5b557f/rav1e-0.8.1/src/util/align.rs
Line | Count | Source |
1 | | // Copyright (c) 2017-2022, The rav1e contributors. All rights reserved |
2 | | // |
3 | | // This source code is subject to the terms of the BSD 2 Clause License and |
4 | | // the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License |
5 | | // was not distributed with this source code in the LICENSE file, you can |
6 | | // obtain it at www.aomedia.org/license/software. If the Alliance for Open |
7 | | // Media Patent License 1.0 was not distributed with this source code in the |
8 | | // PATENTS file, you can obtain it at www.aomedia.org/license/patent. |
9 | | |
10 | | use std::mem::MaybeUninit; |
11 | | |
12 | | #[repr(align(64))] |
13 | | pub struct Align64; |
14 | | |
15 | | // A 64 byte aligned piece of data. |
16 | | // # Examples |
17 | | // ``` |
18 | | // let mut x: Aligned<[i16; 64 * 64]> = Aligned::new([0; 64 * 64]); |
19 | | // assert!(x.data.as_ptr() as usize % 16 == 0); |
20 | | // |
21 | | // let mut x: Aligned<[i16; 64 * 64]> = Aligned::uninitialized(); |
22 | | // assert!(x.data.as_ptr() as usize % 16 == 0); |
23 | | // ``` |
24 | | pub struct Aligned<T> { |
25 | | _alignment: [Align64; 0], |
26 | | pub data: T, |
27 | | } |
28 | | |
29 | | #[cfg(any(test, feature = "bench"))] |
30 | | impl<const N: usize, T> Aligned<[T; N]> { |
31 | | #[inline(always)] |
32 | | pub fn from_fn<F>(cb: F) -> Self |
33 | | where |
34 | | F: FnMut(usize) -> T, |
35 | | { |
36 | | Aligned { _alignment: [], data: std::array::from_fn(cb) } |
37 | | } |
38 | | } |
39 | | |
40 | | impl<const N: usize, T> Aligned<[MaybeUninit<T>; N]> { |
41 | | #[inline(always)] |
42 | 0 | pub const fn uninit_array() -> Self { |
43 | 0 | Aligned { |
44 | 0 | _alignment: [], |
45 | 0 | // SAFETY: Uninitialized [MaybeUninit<T>; N] is valid. |
46 | 0 | data: unsafe { MaybeUninit::uninit().assume_init() }, |
47 | 0 | } |
48 | 0 | } Unexecuted instantiation: <rav1e::util::align::Aligned<[core::mem::maybe_uninit::MaybeUninit<i8>; 1024]>>::uninit_array Unexecuted instantiation: <rav1e::util::align::Aligned<[core::mem::maybe_uninit::MaybeUninit<u16>; 257]>>::uninit_array Unexecuted instantiation: <rav1e::util::align::Aligned<[core::mem::maybe_uninit::MaybeUninit<i32>; 4096]>>::uninit_array Unexecuted instantiation: <rav1e::util::align::Aligned<[core::mem::maybe_uninit::MaybeUninit<i32>; 64]>>::uninit_array Unexecuted instantiation: <rav1e::util::align::Aligned<[core::mem::maybe_uninit::MaybeUninit<i16>; 1024]>>::uninit_array Unexecuted instantiation: <rav1e::util::align::Aligned<[core::mem::maybe_uninit::MaybeUninit<i32>; 1024]>>::uninit_array Unexecuted instantiation: <rav1e::util::align::Aligned<[core::mem::maybe_uninit::MaybeUninit<i16>; 4096]>>::uninit_array Unexecuted instantiation: <rav1e::util::align::Aligned<[core::mem::maybe_uninit::MaybeUninit<u8>; 257]>>::uninit_array Unexecuted instantiation: <rav1e::util::align::Aligned<[core::mem::maybe_uninit::MaybeUninit<i16>; 1024]>>::uninit_array Unexecuted instantiation: <rav1e::util::align::Aligned<[core::mem::maybe_uninit::MaybeUninit<i32>; 4096]>>::uninit_array Unexecuted instantiation: <rav1e::util::align::Aligned<[core::mem::maybe_uninit::MaybeUninit<i32>; 64]>>::uninit_array Unexecuted instantiation: <rav1e::util::align::Aligned<[core::mem::maybe_uninit::MaybeUninit<i16>; 4096]>>::uninit_array Unexecuted instantiation: <rav1e::util::align::Aligned<[core::mem::maybe_uninit::MaybeUninit<i8>; 1024]>>::uninit_array |
49 | | } |
50 | | |
51 | | impl<T> Aligned<T> { |
52 | 0 | pub const fn new(data: T) -> Self { |
53 | 0 | Aligned { _alignment: [], data } |
54 | 0 | } Unexecuted instantiation: <rav1e::util::align::Aligned<[u16; 16384]>>::new Unexecuted instantiation: <rav1e::util::align::Aligned<arrayvec::arrayvec::ArrayVec<i32, 1024>>>::new Unexecuted instantiation: <rav1e::util::align::Aligned<[core::mem::maybe_uninit::MaybeUninit<u32>; 1024]>>::new Unexecuted instantiation: <rav1e::util::align::Aligned<[u8; 16384]>>::new Unexecuted instantiation: <rav1e::util::align::Aligned<arrayvec::arrayvec::ArrayVec<i16, 1024>>>::new |
55 | | #[allow(clippy::uninit_assumed_init)] |
56 | | /// # Safety |
57 | | /// |
58 | | /// The resulting `Aligned<T>` *must* be written to before it is read from. |
59 | 0 | pub const unsafe fn uninitialized() -> Self { |
60 | 0 | Self::new(MaybeUninit::uninit().assume_init()) |
61 | 0 | } Unexecuted instantiation: <rav1e::util::align::Aligned<[u16; 16384]>>::uninitialized Unexecuted instantiation: <rav1e::util::align::Aligned<[u8; 16384]>>::uninitialized |
62 | | } |
63 | | |
64 | | #[cfg(test)] |
65 | | mod test { |
66 | | use super::*; |
67 | | |
68 | | fn is_aligned<T>(ptr: *const T, n: usize) -> bool { |
69 | | ((ptr as usize) & ((1 << n) - 1)) == 0 |
70 | | } |
71 | | |
72 | | #[test] |
73 | | fn sanity_stack() { |
74 | | let a: Aligned<_> = Aligned::new([0u8; 3]); |
75 | | assert!(is_aligned(a.data.as_ptr(), 4)); |
76 | | } |
77 | | } |