1#![forbid(unsafe_code)]
2#![cfg_attr(not(test), no_std)]
3
4use self::traits::*;
63
64pub trait ArrayTools: Sized + Sealed {
75 type Element;
87
88 const LEN: usize;
98
99 fn as_slice(&self) -> &[Self::Element];
111
112 fn as_mut_slice(&mut self) -> &mut [Self::Element];
124
125 type Tuple;
136
137 fn from_tuple(tuple: Self::Tuple) -> Self;
147
148 fn into_tuple(self) -> Self::Tuple;
158
159 fn generate<F>(f: F) -> Self
173 where Self: ArrayGenerate<F>
174 {
175 ArrayGenerate::generate(f)
176 }
177
178 fn repeat<T: Clone>(x: T) -> Self
193 where Self: ArrayRepeat<T>
194 {
195 ArrayRepeat::repeat(x)
196 }
197
198 fn from_iter<I: IntoIterator>(it: I) -> Option<Self>
216 where Self: ArrayFromIter<I::IntoIter>
217 {
218 ArrayFromIter::from_iter(it.into_iter())
219 }
220
221 fn indices() -> Self
232 where Self: ArrayIndices
233 {
234 ArrayIndices::indices()
235 }
236
237 #[must_use = "if you don't need the result, use `for_each`"]
249 fn map<F>(self, f: F) -> <Self as ArrayMap<F>>::Output
250 where Self: ArrayMap<F>
251 {
252 ArrayMap::map(self, f)
253 }
254
255 fn for_each<F>(self, f: F)
269 where Self: ArrayMap<F, OutputElement = ()>
270 {
271 ArrayMap::map(self, f);
272 }
273
274 fn zip<T>(self, other: T) -> <Self as ArrayZip<T>>::Output
284 where Self: ArrayZip<T>
285 {
286 ArrayZip::zip(self, other)
287 }
288
289 fn zip_with<T, F>(self, other: T, f: F) -> <Self as ArrayZipWith<T, F>>::Output
301 where Self: ArrayZipWith<T, F>
302 {
303 ArrayZipWith::zip_with(self, other, f)
304 }
305
306 fn as_ref_array<'a>(&'a self) -> <Self as ArrayAsRef<'a>>::Output
317 where Self: ArrayAsRef<'a>
318 {
319 ArrayAsRef::as_ref(self)
320 }
321
322 fn as_mut_array<'a>(&'a mut self) -> <Self as ArrayAsMut<'a>>::Output
333 where Self: ArrayAsMut<'a>
334 {
335 ArrayAsMut::as_mut(self)
336 }
337
338 #[must_use = "this returns the new array; it doesn't update the existing one"]
348 fn push_back<U>(self, item: U) -> <Self as ArrayPush<U>>::Output
349 where Self: ArrayPush<U>
350 {
351 ArrayPush::push_back(self, item)
352 }
353
354 #[must_use = "this returns the new array; it doesn't update the existing one"]
364 fn push_front<U>(self, item: U) -> <Self as ArrayPush<U>>::Output
365 where Self: ArrayPush<U>
366 {
367 ArrayPush::push_front(self, item)
368 }
369
370 #[must_use = "this returns the new array; it doesn't update the existing one"]
381 fn pop_back<U>(self) -> (<Self as ArrayPop<U>>::Output, U)
382 where Self: ArrayPop<U>
383 {
384 ArrayPop::pop_back(self)
385 }
386
387 #[must_use = "this returns the new array; it doesn't update the existing one"]
398 fn pop_front<U>(self) -> (<Self as ArrayPop<U>>::Output, U)
399 where Self: ArrayPop<U>
400 {
401 ArrayPop::pop_front(self)
402 }
403}
404
405mod traits {
406 pub trait Sealed {}
407
408 pub trait ArrayGenerate<F> {
409 fn generate(f: F) -> Self;
410 }
411
412 pub trait ArrayRepeat<T> {
413 fn repeat(x: T) -> Self;
414 }
415
416 pub trait ArrayFromIter<I> {
417 fn from_iter(it: I) -> Option<Self> where Self: Sized;
418 }
419
420 pub trait ArrayIndices {
421 fn indices() -> Self;
422 }
423
424 pub trait ArrayMap<F> {
425 type Output;
426 type OutputElement;
427 fn map(array: Self, f: F) -> Self::Output;
428 }
429
430 pub trait ArrayZip<T> {
431 type Output;
432 fn zip(array: Self, other: T) -> Self::Output;
433 }
434
435 pub trait ArrayZipWith<T, F> {
436 type Output;
437 fn zip_with(array: Self, other: T, f: F) -> Self::Output;
438 }
439
440 pub trait ArrayAsRef<'a> {
441 type Output: 'a;
442 fn as_ref(array: &'a Self) -> Self::Output;
443 }
444
445 pub trait ArrayAsMut<'a> {
446 type Output: 'a;
447 fn as_mut(array: &'a mut Self) -> Self::Output;
448 }
449
450 pub trait ArrayPush<T> {
451 type Output;
452 fn push_back(array: Self, item: T) -> Self::Output;
453 fn push_front(array: Self, item: T) -> Self::Output;
454 }
455
456 pub trait ArrayPop<T> {
457 type Output;
458 fn pop_back(array: Self) -> (Self::Output, T);
459 fn pop_front(array: Self) -> (Self::Output, T);
460 }
461}
462
463#[allow(unused_mut, unused_variables)]
464mod impls {
465 use super::*;
466
467 macro_rules! replace_ident {
468 ($i:ident => $($j:tt)*) => ($($j)*)
469 }
470
471 macro_rules! array_by_cloning {
472 ($x:ident:) => ( [] );
473 ($x:ident: $first:ident $($i:ident)*) => ( [$(replace_ident!($i => $x.clone()),)* $x] );
474 }
475
476 macro_rules! impl_for_size {
477 ($n:expr; $fn_trait:ident => $($i:ident)* / $($j:ident)*) => (
478
479 impl<T> Sealed for [T; $n] {}
480 impl<T> ArrayTools for [T; $n] {
481 type Element = T;
482 const LEN: usize = $n;
483 fn as_slice(&self) -> &[Self::Element] { self }
484 fn as_mut_slice(&mut self) -> &mut [Self::Element] { self }
485
486 type Tuple = ($(replace_ident!($i => T),)*);
487 fn from_tuple(tuple: Self::Tuple) -> Self {
488 let ($($i,)*) = tuple;
489 [$($i,)*]
490 }
491 fn into_tuple(self) -> Self::Tuple {
492 let [$($i,)*] = self;
493 ($($i,)*)
494 }
495 }
496 impl<T, F> ArrayGenerate<F> for [T; $n]
497 where F: $fn_trait() -> T
498 {
499 fn generate(mut f: F) -> Self {
500 [$(replace_ident!($i => f()),)*]
501 }
502 }
503 impl<T> ArrayRepeat<T> for [T; $n]
504 where T: Clone
505 {
506 fn repeat(x: T) -> Self {
507 array_by_cloning!(x: $($i)*)
508 }
509 }
510 impl<T, I> ArrayFromIter<I> for [T; $n]
511 where I: Iterator<Item = T>
512 {
513 fn from_iter(mut it: I) -> Option<Self> {
514 Some([$(replace_ident!($i => it.next()?),)*])
515 }
516 }
517 impl ArrayIndices for [usize; $n] {
518 fn indices() -> Self {
519 let mut i = 0;
520 ArrayTools::generate(|| { let t = i; i += 1; t })
521 }
522 }
523 impl<T, U, F> ArrayMap<F> for [T; $n]
524 where F: $fn_trait(T) -> U
525 {
526 type Output = [U; $n];
527 type OutputElement = U;
528 fn map(array: Self, mut f: F) -> Self::Output {
529 let [$($i,)*] = array;
530 [$(f($i),)*]
531 }
532 }
533 impl<T, U> ArrayZip<[U; $n]> for [T; $n] {
534 type Output = [(T, U); $n];
535 fn zip(array: Self, other: [U; $n]) -> Self::Output {
536 let [$($i,)*] = array;
537 let [$($j,)*] = other;
538 [$(($i,$j),)*]
539 }
540 }
541 impl<T, U, V, F> ArrayZipWith<[U; $n], F> for [T; $n]
542 where F: $fn_trait(T, U) -> V
543 {
544 type Output = [V; $n];
545 fn zip_with(array: Self, other: [U; $n], mut f: F) -> Self::Output {
546 let [$($i,)*] = array;
547 let [$($j,)*] = other;
548 [$(f($i,$j),)*]
549 }
550 }
551 impl<'a, T: 'a> ArrayAsRef<'a> for [T; $n]
552 {
553 type Output = [&'a T; $n];
554 fn as_ref(array: &'a Self) -> Self::Output {
555 let [$($i,)*] = array;
556 [$($i,)*]
557 }
558 }
559 impl<'a, T: 'a> ArrayAsMut<'a> for [T; $n]
560 {
561 type Output = [&'a mut T; $n];
562 fn as_mut(array: &'a mut Self) -> Self::Output {
563 let [$($i,)*] = array;
564 [$($i,)*]
565 }
566 }
567 impl<T> ArrayPush<T> for [T; $n] {
568 type Output = [T; $n+1];
569 fn push_back(array: Self, item: T) -> Self::Output {
570 let [$($i,)*] = array;
571 [$($i,)* item]
572 }
573 fn push_front(array: Self, item: T) -> Self::Output {
574 let [$($i,)*] = array;
575 [item, $($i,)*]
576 }
577 }
578 impl<T> ArrayPop<T> for [T; $n+1] {
579 type Output = [T; $n];
580 fn pop_back(array: Self) -> (Self::Output, T) {
581 let [$($i,)* item] = array;
582 ([$($i,)*], item)
583 }
584 fn pop_front(array: Self) -> (Self::Output, T) {
585 let [item, $($i,)*] = array;
586 ([$($i,)*], item)
587 }
588 }
589
590 )
591 }
592
593 impl_for_size!(0; FnOnce => /);
595 impl_for_size!(1; FnOnce => a0 / b0);
596 impl_for_size!(2; FnMut => a0 a1 / b0 b1);
597 impl_for_size!(3; FnMut => a0 a1 a2 / b0 b1 b2);
598 impl_for_size!(4; FnMut => a0 a1 a2 a3 / b0 b1 b2 b3);
599 impl_for_size!(5; FnMut => a0 a1 a2 a3 a4 / b0 b1 b2 b3 b4);
600 impl_for_size!(6; FnMut => a0 a1 a2 a3 a4 a5 / b0 b1 b2 b3 b4 b5);
601 impl_for_size!(7; FnMut => a0 a1 a2 a3 a4 a5 a6 / b0 b1 b2 b3 b4 b5 b6);
602 impl_for_size!(8; FnMut => a0 a1 a2 a3 a4 a5 a6 a7 / b0 b1 b2 b3 b4 b5 b6 b7);
603 impl_for_size!(9; FnMut => a0 a1 a2 a3 a4 a5 a6 a7 a8 / b0 b1 b2 b3 b4 b5 b6 b7 b8);
604 impl_for_size!(10; FnMut => a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 / b0 b1 b2 b3 b4 b5 b6 b7 b8 b9);
605 impl_for_size!(11; FnMut => a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 / b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10);
606 impl_for_size!(12; FnMut => a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 / b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11);
607 impl_for_size!(13; FnMut => a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 / b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12);
608 impl_for_size!(14; FnMut => a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 / b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13);
609 impl_for_size!(15; FnMut => a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 / b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14);
610 impl_for_size!(16; FnMut => a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 / b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15);
611 impl_for_size!(17; FnMut => a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 / b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15 b16);
612 impl_for_size!(18; FnMut => a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 / b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15 b16 b17);
613 impl_for_size!(19; FnMut => a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 / b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15 b16 b17 b18);
614 impl_for_size!(20; FnMut => a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 / b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15 b16 b17 b18 b19);
615 impl_for_size!(21; FnMut => a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20 / b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15 b16 b17 b18 b19 b20);
616 impl_for_size!(22; FnMut => a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20 a21 / b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15 b16 b17 b18 b19 b20 b21);
617 impl_for_size!(23; FnMut => a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20 a21 a22 / b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15 b16 b17 b18 b19 b20 b21 b22);
618 impl_for_size!(24; FnMut => a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20 a21 a22 a23 / b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15 b16 b17 b18 b19 b20 b21 b22 b23);
619 impl_for_size!(25; FnMut => a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20 a21 a22 a23 a24 / b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15 b16 b17 b18 b19 b20 b21 b22 b23 b24);
620 impl_for_size!(26; FnMut => a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20 a21 a22 a23 a24 a25 / b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15 b16 b17 b18 b19 b20 b21 b22 b23 b24 b25);
621 impl_for_size!(27; FnMut => a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20 a21 a22 a23 a24 a25 a26 / b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15 b16 b17 b18 b19 b20 b21 b22 b23 b24 b25 b26);
622 impl_for_size!(28; FnMut => a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20 a21 a22 a23 a24 a25 a26 a27 / b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15 b16 b17 b18 b19 b20 b21 b22 b23 b24 b25 b26 b27);
623 impl_for_size!(29; FnMut => a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20 a21 a22 a23 a24 a25 a26 a27 a28 / b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15 b16 b17 b18 b19 b20 b21 b22 b23 b24 b25 b26 b27 b28);
624 impl_for_size!(30; FnMut => a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20 a21 a22 a23 a24 a25 a26 a27 a28 a29 / b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15 b16 b17 b18 b19 b20 b21 b22 b23 b24 b25 b26 b27 b28 b29);
625 impl_for_size!(31; FnMut => a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20 a21 a22 a23 a24 a25 a26 a27 a28 a29 a30 / b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15 b16 b17 b18 b19 b20 b21 b22 b23 b24 b25 b26 b27 b28 b29 b30);
626 impl_for_size!(32; FnMut => a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20 a21 a22 a23 a24 a25 a26 a27 a28 a29 a30 a31 / b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15 b16 b17 b18 b19 b20 b21 b22 b23 b24 b25 b26 b27 b28 b29 b30 b31);
627}
628
629#[cfg(test)]
630mod tests {
631 use super::ArrayTools;
632
633 #[test]
634 fn it_works() {
635 let mut a = [1];
636 *a.as_mut_array()[0] = 2;
637 assert_eq!(a, [2]);
638
639 a = ArrayTools::from_tuple((3,));
640 assert_eq!(a, [3]);
641 assert_eq!(a.into_tuple(), (3,));
642
643 let a = a.map(|x| x as f32);
644 assert_eq!(a, [3.0]);
645
646 let a0: [u8; 0] = [];
647 let a1 = a0.push_back(Default::default());
648 assert_eq!(a1, [0]);
649 let a2 = a1.push_back(2);
650 assert_eq!(a2, [0, 2]);
651 let b1 = a2.pop_back();
652 assert_eq!(b1, ([0], 2));
653
654 let iota: [_; 10] = ArrayTools::indices();
655 assert_eq!(iota, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
656
657 let mut v = Vec::with_capacity(111);
658 v.push(1);
659 let a: [_; 3] = ArrayTools::repeat(v);
660 assert_eq!(a[0], [1]);
661 assert_eq!(a[1], [1]);
662 assert_eq!(a[2], [1]);
663 assert_eq!(a[0].capacity(), 1);
664 assert_eq!(a[1].capacity(), 1);
665 assert_eq!(a[2].capacity(), 111);
666
667 let sums = [1, 2, 3].zip_with([30, 20, 10], std::ops::Add::add);
668 assert_eq!(sums, [31, 22, 13]);
669 }
670
671 #[test]
672 fn from_iter_is_not_ambiguous_with_std() {
673 #[allow(unused_imports)]
674 use std::iter::FromIterator;
675 <[i16; 5]>::from_iter(1..);
676 }
677}