1#![no_std]
35#![allow(incomplete_features)]
36#![feature(generic_const_exprs)]
37
38pub trait SplitArray<const LEN: usize> {
40 type Output<const OUT_SIZE: usize>: SplitArray<OUT_SIZE>;
42
43 fn split_arr<const LEFT: usize>(&self) -> (&Self::Output<LEFT>, &Self::Output<{ LEN - LEFT }>)
47 where
48 [(); LEN - LEFT]:;
49
50 fn split_arr_mut<const LEFT: usize>(
52 &mut self,
53 ) -> (&mut Self::Output<LEFT>, &mut Self::Output<{ LEN - LEFT }>)
54 where
55 [(); LEN - LEFT]:;
56}
57
58pub trait SplitArrayRaw<const LEN: usize> {
60 type Output<const OUT_SIZE: usize>: SplitArrayRaw<OUT_SIZE>;
62
63 unsafe fn split_arr_raw<const LEFT: usize>(
70 self,
71 ) -> (Self::Output<LEFT>, Self::Output<{ LEN - LEFT }>)
72 where
73 [(); LEN - LEFT]:;
74}
75
76pub trait SplitArrayRawMut<const LEN: usize> {
78 type Output<const OUT_SIZE: usize>: SplitArrayRawMut<OUT_SIZE>;
79
80 unsafe fn split_arr_raw_mut<const LEFT: usize>(
87 self,
88 ) -> (Self::Output<LEFT>, Self::Output<{ LEN - LEFT }>)
89 where
90 [(); LEN - LEFT]:;
91}
92
93impl<T, const LEN: usize> SplitArray<LEN> for [T; LEN] {
94 type Output<const OUT_SIZE: usize> = [T; OUT_SIZE];
95
96 #[inline]
97 fn split_arr<const LEFT: usize>(&self) -> (&[T; LEFT], &[T; LEN - LEFT])
98 where
99 [(); LEN - LEFT]:,
100 {
101 split_arr(self)
102 }
103
104 #[inline]
105 fn split_arr_mut<const LEFT: usize>(&mut self) -> (&mut [T; LEFT], &mut [T; LEN - LEFT])
106 where
107 [(); LEN - LEFT]:,
108 {
109 split_arr_mut(self)
110 }
111}
112
113impl<T, const LEN: usize> SplitArrayRaw<LEN> for *const [T; LEN] {
114 type Output<const OUT_SIZE: usize> = *const [T; OUT_SIZE];
115
116 unsafe fn split_arr_raw<const LEFT: usize>(self) -> (*const [T; LEFT], *const [T; LEN - LEFT])
117 where
118 [(); LEN - LEFT]:,
119 {
120 unsafe { split_arr_raw(self) }
121 }
122}
123
124impl<T, const LEN: usize> SplitArrayRawMut<LEN> for *mut [T; LEN] {
125 type Output<const OUT_SIZE: usize> = *mut [T; OUT_SIZE];
126
127 unsafe fn split_arr_raw_mut<const LEFT: usize>(self) -> (*mut [T; LEFT], *mut [T; LEN - LEFT])
128 where
129 [(); LEN - LEFT]:,
130 {
131 unsafe { split_arr_raw_mut(self) }
132 }
133}
134
135#[inline]
139pub const fn split_arr<const LEFT: usize, const N: usize, T>(
140 arr: &[T; N],
141) -> (&[T; LEFT], &[T; N - LEFT])
142where
143 [(); N - LEFT]:,
144{
145 unsafe {
146 let (left, right) = split_arr_raw(arr);
147 (&*left, &*right)
148 }
149}
150
151#[inline]
153pub fn split_arr_mut<const LEFT: usize, const N: usize, T>(
154 arr: &mut [T; N],
155) -> (&mut [T; LEFT], &mut [T; N - LEFT])
156where
157 [(); N - LEFT]:,
158{
159 unsafe {
160 let (left, right) = split_arr_raw_mut(arr);
161 (&mut *left, &mut *right)
162 }
163}
164
165#[inline]
170pub const unsafe fn split_arr_raw<const LEFT: usize, const N: usize, T>(
171 arr: *const [T; N],
172) -> (*const [T; LEFT], *const [T; N - LEFT])
173where
174 [(); N - LEFT]:,
175{
176 let left = arr.cast::<T>();
177 let right = unsafe { left.add(LEFT) };
178
179 (left.cast(), right.cast())
180}
181
182#[inline]
187pub const unsafe fn split_arr_raw_mut<const LEFT: usize, const N: usize, T>(
188 arr: *mut [T; N],
189) -> (*mut [T; LEFT], *mut [T; N - LEFT])
190where
191 [(); N - LEFT]:,
192{
193 let left = arr as *mut T;
194 let right = unsafe { left.add(LEFT) };
195
196 (left.cast(), right.cast())
197}
198
199#[cfg(test)]
200mod tests {
201 use super::*;
202 use core::ptr::{addr_of, addr_of_mut};
203
204 #[test]
205 fn split_arr() {
206 let arr: [usize; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
207 let (left, right) = arr.split_arr::<5>();
208
209 assert_eq!(&[0, 1, 2, 3, 4], left);
210 assert_eq!(&[5, 6, 7], right);
211 }
212
213 #[test]
214 fn split_arr_infer_size() {
215 let arr: [usize; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
216 let (left, right) = arr.split_arr();
217
218 assert_eq!(&[0, 1, 2, 3, 4], left);
219 assert_eq!(&[5, 6, 7], right);
220 }
221
222 #[test]
223 fn split_arr_left_zero() {
224 let arr: [usize; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
225 let (left, right) = arr.split_arr::<0>();
226
227 assert_eq!(&[0; 0], left);
228 assert_eq!(&[0, 1, 2, 3, 4, 5, 6, 7], right);
229 }
230
231 #[test]
232 fn split_arr_right_zero() {
233 let arr: [usize; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
234 let (left, right) = arr.split_arr::<8>();
235
236 assert_eq!(&[0, 1, 2, 3, 4, 5, 6, 7], left);
237 assert_eq!(&[0; 0], right);
238 }
239
240 #[test]
241 fn split_arr_mut() {
242 let mut arr: [usize; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
243 let (left, right) = arr.split_arr_mut::<5>();
244 left.clone_from(&[10, 11, 12, 13, 14]);
245 right.clone_from(&[25, 26, 27]);
246
247 assert_eq!(&[10, 11, 12, 13, 14], left);
248 assert_eq!(&[25, 26, 27], right);
249 assert_eq!([10, 11, 12, 13, 14, 25, 26, 27], arr);
250 }
251
252 #[test]
253 fn split_arr_mut_infer_size() {
254 let mut arr: [usize; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
255 let (left, right) = arr.split_arr_mut();
256 left.clone_from(&[10, 11, 12, 13, 14]);
257 right.clone_from(&[25, 26, 27]);
258
259 assert_eq!(&[10, 11, 12, 13, 14], left);
260 assert_eq!(&[25, 26, 27], right);
261 assert_eq!([10, 11, 12, 13, 14, 25, 26, 27], arr);
262 }
263
264 #[test]
265 fn split_arr_mut_left_zero() {
266 let mut arr: [usize; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
267 let (left, right) = arr.split_arr_mut::<0>();
268 left.clone_from(&[]);
269 right.clone_from(&[20, 21, 22, 23, 24, 25, 26, 27]);
270
271 assert_eq!(&[0; 0], left);
272 assert_eq!(&[20, 21, 22, 23, 24, 25, 26, 27], right);
273 assert_eq!([20, 21, 22, 23, 24, 25, 26, 27], arr);
274 }
275
276 #[test]
277 fn split_arr_mut_right_zero() {
278 let mut arr: [usize; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
279 let (left, right) = arr.split_arr_mut::<8>();
280 left.clone_from(&[10, 11, 12, 13, 14, 15, 16, 17]);
281 right.clone_from(&[]);
282
283 assert_eq!(&[10, 11, 12, 13, 14, 15, 16, 17], left);
284 assert_eq!(&[0; 0], right);
285 assert_eq!([10, 11, 12, 13, 14, 15, 16, 17], arr);
286 }
287
288 #[test]
289 fn split_arr_raw() {
290 let arr: [usize; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
291
292 unsafe {
293 let (left, right) = addr_of!(arr).split_arr_raw::<5>();
294
295 assert_eq!([0, 1, 2, 3, 4], *left);
296 assert_eq!([5, 6, 7], *right);
297 }
298 }
299
300 #[test]
301 fn split_arr_raw_infer_size() {
302 let arr: [usize; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
303
304 unsafe {
305 let (left, right) = addr_of!(arr).split_arr_raw();
306
307 assert_eq!([0, 1, 2, 3, 4], *left);
308 assert_eq!([5, 6, 7], *right);
309 }
310 }
311
312 #[test]
313 fn split_arr_raw_left_zero() {
314 let arr: [usize; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
315
316 unsafe {
317 let (left, right) = addr_of!(arr).split_arr_raw::<0>();
318
319 assert_eq!([0; 0], *left);
320 assert_eq!([0, 1, 2, 3, 4, 5, 6, 7], *right);
321 }
322 }
323
324 #[test]
325 fn split_arr_raw_right_zero() {
326 let arr: [usize; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
327
328 unsafe {
329 let (left, right) = addr_of!(arr).split_arr_raw::<8>();
330
331 assert_eq!([0, 1, 2, 3, 4, 5, 6, 7], *left);
332 assert_eq!([0; 0], *right);
333 }
334 }
335
336 #[test]
337 fn split_arr_raw_mut() {
338 let mut arr: [usize; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
339
340 unsafe {
341 let (left, right) = addr_of_mut!(arr).split_arr_raw_mut::<5>();
342 *left = [10, 11, 12, 13, 14];
343 *right = [25, 26, 27];
344
345 assert_eq!([10, 11, 12, 13, 14], *left);
346 assert_eq!([25, 26, 27], *right);
347 }
348
349 assert_eq!([10, 11, 12, 13, 14, 25, 26, 27], arr);
350 }
351
352 #[test]
353 fn split_arr_raw_mut_infer_size() {
354 let mut arr: [usize; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
355
356 unsafe {
357 let (left, right) = addr_of_mut!(arr).split_arr_raw_mut();
358 *left = [10, 11, 12, 13, 14];
359 *right = [25, 26, 27];
360
361 assert_eq!([10, 11, 12, 13, 14], *left);
362 assert_eq!([25, 26, 27], *right);
363 }
364
365 assert_eq!([10, 11, 12, 13, 14, 25, 26, 27], arr);
366 }
367
368 #[test]
369 fn split_arr_raw_mut_left_zero() {
370 let mut arr: [usize; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
371
372 unsafe {
373 let (left, right) = addr_of_mut!(arr).split_arr_raw_mut::<0>();
374 *left = [];
375 *right = [20, 21, 22, 23, 24, 25, 26, 27];
376
377 assert_eq!([0; 0], *left);
378 assert_eq!([20, 21, 22, 23, 24, 25, 26, 27], *right);
379 }
380
381 assert_eq!([20, 21, 22, 23, 24, 25, 26, 27], arr);
382 }
383
384 #[test]
385 fn split_arr_raw_mut_right_zero() {
386 let mut arr: [usize; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
387
388 unsafe {
389 let (left, right) = addr_of_mut!(arr).split_arr_raw_mut::<8>();
390 *left = [10, 11, 12, 13, 14, 15, 16, 17];
391 *right = [];
392
393 assert_eq!([10, 11, 12, 13, 14, 15, 16, 17], *left);
394 assert_eq!([0; 0], *right);
395 }
396
397 assert_eq!([10, 11, 12, 13, 14, 15, 16, 17], arr);
398 }
399
400 #[test]
401 fn array_impl_defers() {
402 let arr: [usize; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
403 assert_eq!(crate::split_arr(&arr), arr.split_arr::<5>());
404 }
405
406 #[test]
407 fn array_impl_defers_mut() {
408 let mut arr: [usize; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
409 let (crate_level_left, crate_level_right) = crate::split_arr_mut(&mut arr);
410 let crate_level_result = (crate_level_left as *mut _, crate_level_right as *mut _);
411 let (trait_left, trait_right) = arr.split_arr_mut::<5>();
412 let trait_result = (trait_left as *mut _, trait_right as *mut _);
413 assert_eq!(crate_level_result, trait_result);
414 }
415
416 #[test]
417 fn array_impl_defers_raw() {
418 let arr: [usize; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
419 unsafe {
420 assert_eq!(
421 crate::split_arr_raw(addr_of!(arr)),
422 addr_of!(arr).split_arr_raw::<5>()
423 );
424 }
425 }
426
427 #[test]
428 fn array_impl_defers_raw_mut() {
429 let mut arr: [usize; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
430 unsafe {
431 assert_eq!(
432 crate::split_arr_raw_mut(addr_of_mut!(arr)),
433 addr_of_mut!(arr).split_arr_raw_mut::<5>()
434 );
435 }
436 }
437}