1#![no_std]
2
3use core::marker::PhantomData;
4
5pub unsafe trait RecursiveArray<T>: Sized + AsRef<[T]> + AsMut<[T]> {
8 const LENGTH: usize;
10
11 const EMPTY: EmptyRecursiveArray = EmptyRecursiveArray;
13
14 fn empty() -> EmptyRecursiveArray {
16 EmptyRecursiveArray
17 }
18
19 fn len(&self) -> usize {
21 Self::LENGTH
22 }
23
24 fn from_array<const N: usize>(array: [T; N]) -> Self {
31 if N != Self::LENGTH {
32 panic!(
33 "tried to convert an array of length {} to a recursive array of length {}",
34 N,
35 Self::LENGTH,
36 );
37 }
38 unsafe { runtime_checked_transmute(array) }
39 }
40
41 fn to_array<const N: usize>(self) -> [T; N] {
48 if N != Self::LENGTH {
49 panic!(
50 "tried to convert a recursive array of length {} to an array of length {}",
51 Self::LENGTH,
52 N,
53 );
54 }
55 unsafe { runtime_checked_transmute(self) }
56 }
57
58 fn from_slice(slice: &[T]) -> &Self {
64 if slice.len() != Self::LENGTH {
65 panic!(
66 "tried to convert a slice of length {} to a recursive array of length {}",
67 slice.len(),
68 Self::LENGTH,
69 );
70 }
71 unsafe { &*slice.as_ptr().cast() }
72 }
73
74 fn from_mut_slice(slice: &mut [T]) -> &mut Self {
80 if slice.len() != Self::LENGTH {
81 panic!(
82 "tried to convert a slice of length {} to a recursive array of length {}",
83 slice.len(),
84 Self::LENGTH,
85 );
86 }
87 unsafe { &mut *slice.as_mut_ptr().cast() }
88 }
89
90 fn as_slice(&self) -> &[T] {
92 unsafe { core::slice::from_raw_parts(self as *const Self as *const T, Self::LENGTH) }
93 }
94
95 fn as_mut_slice(&mut self) -> &mut [T] {
97 unsafe { core::slice::from_raw_parts_mut(self as *mut Self as *mut T, Self::LENGTH) }
98 }
99
100 fn push_back(
102 self,
103 item: T,
104 ) -> RecursiveArrayConcatenation<T, Self, RecursiveArraySingleItem<T>> {
105 RecursiveArrayConcatenation::new(self, RecursiveArraySingleItem::new(item))
106 }
107
108 fn append_back<R: RecursiveArray<T>>(
110 self,
111 array: R,
112 ) -> RecursiveArrayConcatenation<T, Self, R> {
113 RecursiveArrayConcatenation::new(self, array)
114 }
115
116 fn push_front(
118 self,
119 item: T,
120 ) -> RecursiveArrayConcatenation<T, RecursiveArraySingleItem<T>, Self> {
121 RecursiveArrayConcatenation::new(RecursiveArraySingleItem::new(item), self)
122 }
123
124 fn append_front<R: RecursiveArray<T>>(
126 self,
127 array: R,
128 ) -> RecursiveArrayConcatenation<T, R, Self> {
129 RecursiveArrayConcatenation::new(array, self)
130 }
131}
132
133#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Default)]
135pub struct EmptyRecursiveArray;
136impl<T> AsRef<[T]> for EmptyRecursiveArray {
137 fn as_ref(&self) -> &[T] {
138 &[]
139 }
140}
141impl<T> AsMut<[T]> for EmptyRecursiveArray {
142 fn as_mut(&mut self) -> &mut [T] {
143 &mut []
144 }
145}
146unsafe impl<T> RecursiveArray<T> for EmptyRecursiveArray {
147 const LENGTH: usize = 0;
148}
149
150#[derive(Debug, Clone, Hash, PartialEq, Eq, Default)]
152#[repr(transparent)]
153pub struct RecursiveArraySingleItem<T> {
154 item: T,
155}
156impl<T> AsRef<[T]> for RecursiveArraySingleItem<T> {
157 fn as_ref(&self) -> &[T] {
158 self.as_slice()
159 }
160}
161impl<T> AsMut<[T]> for RecursiveArraySingleItem<T> {
162 fn as_mut(&mut self) -> &mut [T] {
163 self.as_mut_slice()
164 }
165}
166unsafe impl<T> RecursiveArray<T> for RecursiveArraySingleItem<T> {
167 const LENGTH: usize = 1;
168}
169impl<T> RecursiveArraySingleItem<T> {
170 pub fn new(item: T) -> Self {
172 Self { item }
173 }
174}
175
176#[derive(Debug, Clone, Hash, PartialEq, Eq, Default)]
178#[repr(C)]
179pub struct RecursiveArrayConcatenation<T, A: RecursiveArray<T>, B: RecursiveArray<T>> {
180 a: A,
181 b: B,
182 phantom: PhantomData<T>,
183}
184impl<T, A: RecursiveArray<T>, B: RecursiveArray<T>> AsRef<[T]>
185 for RecursiveArrayConcatenation<T, A, B>
186{
187 fn as_ref(&self) -> &[T] {
188 self.as_slice()
189 }
190}
191impl<T, A: RecursiveArray<T>, B: RecursiveArray<T>> AsMut<[T]>
192 for RecursiveArrayConcatenation<T, A, B>
193{
194 fn as_mut(&mut self) -> &mut [T] {
195 self.as_mut_slice()
196 }
197}
198unsafe impl<T, A: RecursiveArray<T>, B: RecursiveArray<T>> RecursiveArray<T>
199 for RecursiveArrayConcatenation<T, A, B>
200{
201 const LENGTH: usize = A::LENGTH + B::LENGTH;
202}
203impl<T, A: RecursiveArray<T>, B: RecursiveArray<T>> RecursiveArrayConcatenation<T, A, B> {
204 pub fn new(a: A, b: B) -> Self {
206 Self {
207 a,
208 b,
209 phantom: PhantomData,
210 }
211 }
212}
213impl<T, A: RecursiveArray<T>> RecursiveArrayConcatenation<T, A, RecursiveArraySingleItem<T>> {
214 pub fn pop_back(self) -> (T, A) {
217 (self.b.item, self.a)
218 }
219}
220
221impl<T, B: RecursiveArray<T>> RecursiveArrayConcatenation<T, RecursiveArraySingleItem<T>, B> {
222 pub fn pop_front(self) -> (T, B) {
225 (self.a.item, self.b)
226 }
227}
228
229#[derive(Debug, Clone, Hash, PartialEq, Eq)]
231#[repr(transparent)]
232pub struct RecursiveArrayArrayWrapper<const N: usize, T> {
233 array: [T; N],
234}
235impl<const N: usize, T> RecursiveArrayArrayWrapper<N, T> {
236 pub fn new(array: [T; N]) -> Self {
238 Self { array }
239 }
240}
241impl<const N: usize, T> AsRef<[T]> for RecursiveArrayArrayWrapper<N, T> {
242 fn as_ref(&self) -> &[T] {
243 self.as_slice()
244 }
245}
246impl<const N: usize, T> AsMut<[T]> for RecursiveArrayArrayWrapper<N, T> {
247 fn as_mut(&mut self) -> &mut [T] {
248 self.as_mut_slice()
249 }
250}
251unsafe impl<const N: usize, T> RecursiveArray<T> for RecursiveArrayArrayWrapper<N, T> {
252 const LENGTH: usize = N;
253}
254
255#[derive(Debug, Clone, Hash, PartialEq, Eq)]
257#[repr(transparent)]
258pub struct RecursiveArrayMultiplier<const N: usize, T, A: RecursiveArray<T>> {
259 multiplied: [A; N],
260 phantom: PhantomData<T>,
261}
262impl<const N: usize, T, A: RecursiveArray<T>> RecursiveArrayMultiplier<N, T, A> {
263 pub fn new(values: [A; N]) -> Self {
265 Self {
266 multiplied: values,
267 phantom: PhantomData,
268 }
269 }
270}
271impl<const N: usize, T, A: RecursiveArray<T>> AsRef<[T]> for RecursiveArrayMultiplier<N, T, A> {
272 fn as_ref(&self) -> &[T] {
273 self.as_slice()
274 }
275}
276impl<const N: usize, T, A: RecursiveArray<T>> AsMut<[T]> for RecursiveArrayMultiplier<N, T, A> {
277 fn as_mut(&mut self) -> &mut [T] {
278 self.as_mut_slice()
279 }
280}
281unsafe impl<const N: usize, T, A: RecursiveArray<T>> RecursiveArray<T>
282 for RecursiveArrayMultiplier<N, T, A>
283{
284 const LENGTH: usize = A::LENGTH * N;
285}
286
287#[macro_export]
289macro_rules! recursive_array {
290 [] => {
291 ::recursive_array::EmptyRecursiveArray
292 };
293 [$item: expr $(,)?] => {
294 ::recursive_array::RecursiveArraySingleItem::new($item)
295 };
296 [$first_item: expr, $($item: expr),+] => {
297 ::recursive_array::RecursiveArrayConcatenation::new(
298 ::recursive_array::RecursiveArraySingleItem::new($first_item),
299 ::recursive_array::recursive_array![$($item),+],
300 )
301 };
302}
303
304#[macro_export]
306macro_rules! recursive_array_type_of_size {
307 ($item_type: ty, $size: expr) => {
308 ::recursive_array::RecursiveArrayArrayWrapper<{$size}, $item_type>
309 };
310}
311
312unsafe fn runtime_checked_transmute<A, B>(a: A) -> B {
318 if core::mem::size_of::<A>() != core::mem::size_of::<B>() {
319 panic!(
320 "tried to transmute a type of size {} to a type of size {}",
321 core::mem::size_of::<A>(),
322 core::mem::size_of::<B>()
323 );
324 }
325
326 #[repr(C)]
327 union Union<A, B> {
328 a: core::mem::ManuallyDrop<A>,
329 b: core::mem::ManuallyDrop<B>,
330 }
331
332 let a = core::mem::ManuallyDrop::new(a);
333 core::mem::ManuallyDrop::into_inner(Union { a }.b)
334}