ggmath/alignment.rs
1/// Marker type indicating SIMD-aligned math types.
2///
3/// For more details, see [`Alignment`].
4pub struct Aligned;
5
6/// Marker type indicating non SIMD-aligned math types.
7///
8/// For more details, see [`Alignment`].
9pub struct Unaligned;
10
11/// Marker trait controlling SIMD alignment for math types.
12///
13/// Math types such as [`Vector`](crate::Vector) are generic over `A:
14/// Alignment`, which controls whether the type is SIMD-aligned:
15///
16/// - [`Aligned`]: The type may be SIMD-aligned when doing so improves
17/// performance.
18/// - [`Unaligned`]: The type is never SIMD-aligned.
19///
20/// # Background
21///
22/// [SIMD
23/// instructions](https://en.wikipedia.org/wiki/Single_instruction,_multiple_data)
24/// can significantly improve the performance of math code, but they require
25/// stricter [memory
26/// alignment](https://doc.rust-lang.org/reference/type-layout.html) than scalar
27/// code. For example, a `Vec3<f32>` must be aligned to 16 bytes to efficiently
28/// use SIMD. This increases its size from 12 bytes to 16 bytes, introducing 4
29/// bytes of padding.
30///
31/// In many cases padding is worthwhile for performance, but in other cases such
32/// as storing large arrays, minimizing memory usage is more important.
33///
34/// To support both cases, math types such as [`Vector`](crate::Vector) are
35/// generic over `A: Alignment`, allowing SIMD alignment to be enabled or
36/// disabled as needed. The default type aliases (e.g.,
37/// [`Vec2<T>`](crate::Vec2), [`Vec3<T>`](crate::Vec3)) use [`Aligned`]. Aliases
38/// ending in `U` (e.g., [`Vec2U<T>`](crate::Vec2U), [`Vec3U<T>`](crate::Vec3U))
39/// use [`Unaligned`].
40#[expect(private_bounds)]
41pub trait Alignment: Sealed {
42 #[doc(hidden)]
43 const IS_ALIGNED: bool;
44
45 #[doc(hidden)]
46 type Select<A: Copy, U: Copy>: Copy;
47}
48
49impl Alignment for Aligned {
50 const IS_ALIGNED: bool = true;
51
52 type Select<A: Copy, U: Copy> = A;
53}
54
55impl Alignment for Unaligned {
56 const IS_ALIGNED: bool = false;
57
58 type Select<A: Copy, U: Copy> = U;
59}
60
61trait Sealed: 'static {}
62
63impl Sealed for Aligned {}
64impl Sealed for Unaligned {}