generic_simd/
pointer.rs

1//! Extensions for pointers to vectors.
2
3use crate::{
4    scalar::Scalar,
5    vector::{width, Native, NativeWidth, Vector},
6};
7
8/// A pointer to a vector.
9pub trait Pointer<Token, Width>: Copy
10where
11    Token: crate::arch::Token,
12    Width: width::Width,
13{
14    type Vector: Vector<Token = Token, Width = Width>;
15
16    /// Read a vector from a pointer.
17    ///
18    /// # Safety
19    /// See [`read_ptr`](../vector/trait.Vector.html#method.read_ptr).
20    unsafe fn vector_read(self, token: Token) -> Self::Vector;
21
22    /// Read a vector from a vector-aligned pointer.
23    ///
24    /// # Safety
25    /// See [`read_aligned_ptr`](../vector/trait.Vector.html#method.read_aligned_ptr).
26    unsafe fn vector_read_aligned(self, token: Token) -> Self::Vector;
27}
28
29impl<T, Token, Width> Pointer<Token, Width> for *const T
30where
31    T: Scalar<Token, Width>,
32    Token: crate::arch::Token,
33    Width: width::Width,
34{
35    type Vector = T::Vector;
36
37    #[inline]
38    unsafe fn vector_read(self, token: Token) -> Self::Vector {
39        Self::Vector::read_ptr(token, self)
40    }
41
42    #[inline]
43    unsafe fn vector_read_aligned(self, token: Token) -> Self::Vector {
44        Self::Vector::read_aligned_ptr(token, self)
45    }
46}
47
48impl<T, Token, Width> Pointer<Token, Width> for *mut T
49where
50    T: Scalar<Token, Width>,
51    Token: crate::arch::Token,
52    Width: width::Width,
53{
54    type Vector = T::Vector;
55
56    #[inline]
57    unsafe fn vector_read(self, token: Token) -> Self::Vector {
58        Self::Vector::read_ptr(token, self)
59    }
60
61    #[inline]
62    unsafe fn vector_read_aligned(self, token: Token) -> Self::Vector {
63        Self::Vector::read_aligned_ptr(token, self)
64    }
65}
66
67macro_rules! pointer_impl {
68    {
69        $width:literal,
70        $width_type:ty,
71        $read_unaligned:ident,
72        $read_aligned:ident
73    } => {
74        #[doc = "Read a vector with "]
75        #[doc = $width]
76        #[doc = " from a pointer.\n\n# Safety\nSee [`read_ptr`](../vector/trait.Vector.html#method.read_ptr)."]
77        #[inline]
78        unsafe fn $read_unaligned(self, token: Token) -> <Self as Pointer<Token, $width_type>>::Vector {
79            <Self as Pointer<Token, $width_type>>::vector_read(self, token)
80        }
81
82        #[doc = "Read a vector with "]
83        #[doc = $width]
84        #[doc = " from a vector-aligned pointer.\n\n# Safety\nSee [`read_aligned_ptr`](../vector/trait.Vector.html#method.read_aligned_ptr)."]
85        #[inline]
86        unsafe fn $read_aligned(self, token: Token) -> <Self as Pointer<Token, $width_type>>::Vector {
87            <Self as Pointer<Token, $width_type>>::vector_read_aligned(self, token)
88        }
89    }
90}
91
92/// A pointer to a vector, supporting all vector widths.
93pub trait PointerExt<Token>:
94    Native<Token>
95    + Pointer<Token, width::W1>
96    + Pointer<Token, width::W2>
97    + Pointer<Token, width::W4>
98    + Pointer<Token, width::W8>
99    + Pointer<Token, NativeWidth<Self, Token>>
100where
101    Token: crate::arch::Token,
102{
103    pointer_impl! { "the native number of lanes", <Self as Native<Token>>::Width, vector_read_native, vector_read_aligned_native }
104    pointer_impl! { "1 lane",  width::W1, vector_read1, vector_read1_aligned }
105    pointer_impl! { "2 lanes", width::W2, vector_read2, vector_read2_aligned }
106    pointer_impl! { "4 lanes", width::W4, vector_read4, vector_read4_aligned }
107    pointer_impl! { "8 lanes", width::W8, vector_read8, vector_read8_aligned }
108}
109
110impl<T, Token> PointerExt<Token> for T
111where
112    T: Native<Token>
113        + Pointer<Token, width::W1>
114        + Pointer<Token, width::W2>
115        + Pointer<Token, width::W4>
116        + Pointer<Token, width::W8>
117        + Pointer<Token, NativeWidth<Self, Token>>,
118    Token: crate::arch::Token,
119{
120}