1use core::iter::FusedIterator;
2use core::marker::PhantomData;
3use core::ptr::NonNull;
4
5use crate::access::Access;
6use crate::bounds;
7use crate::integers::Integer;
8use crate::iter;
9use crate::reg::{Reg, RegMapPtr};
10
11#[cfg(doc)]
12use crate::RegMap;
13
14pub struct RegArray<'a, P: ArrayElem<'a>, const N: usize> {
22 ptr: NonNull<[P::Target; N]>,
23 _ref: PhantomData<&'a [P::Target; N]>,
24}
25impl<'a, P: ArrayElem<'a>, const N: usize> RegArray<'a, P, N> {
26 #[doc(hidden)]
37 #[allow(non_snake_case)]
38 #[inline]
39 pub const unsafe fn __MACRO_ONLY__from_ptr(ptr: *mut [P::Target; N]) -> Self {
40 Self::from_nonnull(NonNull::new_unchecked(ptr))
41 }
42 #[inline]
43 const unsafe fn from_nonnull(ptr: NonNull<[P::Target; N]>) -> Self {
44 Self {
45 ptr,
46 _ref: PhantomData,
47 }
48 }
49 #[inline]
51 pub const fn as_ptr(&self) -> *mut [P::Target; N] {
52 self.ptr.as_ptr()
53 }
54 #[allow(clippy::len_without_is_empty)]
56 #[inline]
57 pub const fn len(&self) -> usize {
58 N
59 }
60 #[inline]
65 pub fn idx(&self, index: usize) -> P {
66 bounds::check_index::<N>(index);
67 unsafe { self.idx_unchecked(index) }
69 }
70 #[inline]
75 pub unsafe fn idx_unchecked(&self, index: usize) -> P {
76 let base: NonNull<P::Target> = self.ptr.cast();
77 unsafe { P::from_nonnull(base.add(index)) }
79 }
80 pub fn iter(
82 &self,
83 ) -> impl 'a + ExactSizeIterator<Item = P> + DoubleEndedIterator + FusedIterator + Clone {
84 iter::RegArrayIter::new(self.ptr)
85 }
86 pub fn iter_slice(
91 &self,
92 start: usize,
93 end: usize,
94 ) -> impl 'a + ExactSizeIterator<Item = P> + DoubleEndedIterator + FusedIterator + Clone {
95 bounds::check_slice::<N>(start, end);
96 let base: NonNull<P::Target> = self.ptr.cast();
97 unsafe {
99 let slice = NonNull::slice_from_raw_parts(base.add(start), end - start);
100 iter::RegArrayIter::new(slice)
101 }
102 }
103}
104
105pub trait ArrayElem<'a>: 'a + private::Sealed {
109 type Target;
111
112 unsafe fn from_nonnull(ptr: NonNull<Self::Target>) -> Self;
118}
119
120impl<'a, T: Integer, A: Access> ArrayElem<'a> for Reg<'a, T, A> {
122 type Target = T;
123
124 unsafe fn from_nonnull(ptr: NonNull<Self::Target>) -> Self {
125 Reg::from_nonnull(ptr)
126 }
127}
128
129impl<'a, T: RegMapPtr<'a>> ArrayElem<'a> for T {
131 type Target = T::RegMap;
132
133 unsafe fn from_nonnull(ptr: NonNull<Self::Target>) -> Self {
134 T::from_nonnull(ptr)
135 }
136}
137
138impl<'a, T: ArrayElem<'a>, const N: usize> ArrayElem<'a> for RegArray<'a, T, N> {
140 type Target = [T::Target; N];
141
142 unsafe fn from_nonnull(ptr: NonNull<Self::Target>) -> Self {
143 RegArray::from_nonnull(ptr)
144 }
145}
146
147mod private {
148 use crate::access::Access;
149 use crate::arr::{ArrayElem, RegArray};
150 use crate::integers::Integer;
151 use crate::reg::{Reg, RegMapPtr};
152
153 pub trait Sealed {}
154 impl<'a, T: Integer, A: Access> Sealed for Reg<'a, T, A> {}
155 impl<'a, T: RegMapPtr<'a>> Sealed for T {}
156 impl<'a, T: ArrayElem<'a>, const N: usize> Sealed for RegArray<'a, T, N> {}
157}