arraytools/
lib.rs

1#![forbid(unsafe_code)]
2#![cfg_attr(not(test), no_std)]
3
4//! This crate offers the [`ArrayTools`] extension trait, which provides
5//! a variety of helpful methods for working with fixed-size arrays.
6//!
7//! [`ArrayTools`]: trait.ArrayTools.html
8//!
9//! # Examples
10//!
11//! `Iterator`-like methods over arrays:
12//!
13//! ```rust
14//! use arraytools::ArrayTools;
15//!
16//! assert_eq!([1, 2, 3].map(|x| x+1), [2, 3, 4]);
17//! assert_eq!([1, 2].zip(["one", "two"]), [(1, "one"), (2, "two")]);
18//! ```
19//!
20//! Ways to simplify array creation:
21//!
22//! ```rust
23//! use arraytools::ArrayTools;
24//!
25//! let mut state = 1;
26//! assert_eq!(<[_; 4]>::generate(|| { state *= 2; state }), [2, 4, 8, 16]);
27//! assert_eq!(<[usize; 4]>::indices(), [0, 1, 2, 3]);
28//!
29//! let s = "hello".to_string(); // Something `!Copy`
30//! assert_eq!(<[String; 3]>::repeat(s).as_ref_array(), ["hello", "hello", "hello"]);
31//! ```
32//!
33//! Conversion to and from homogeneous tuples:
34//!
35//! ```rust
36//! use arraytools::ArrayTools;
37//!
38//! let mut array = [2, 3, 5, 7, 11];
39//! assert_eq!(array.into_tuple(), (2, 3, 5, 7, 11));
40//! array = ArrayTools::from_tuple((1, 1, 2, 3, 5));
41//! assert_eq!(array, [1, 1, 2, 3, 5]);
42//! ```
43//!
44//! Like `Option`, most combinators here take `self`.  To not move something,
45//! you can use [`.as_ref_array()`] or [`.as_mut_array()`]:
46//!
47//! [`.as_ref_array()`]: trait.ArrayTools.html#method.as_ref_array
48//! [`.as_mut_array()`]: trait.ArrayTools.html#method.as_mut_array
49//!
50//! ```rust
51//! use arraytools::ArrayTools;
52//!
53//! struct SevenStrings([String; 7]);
54//! impl SevenStrings {
55//!     fn push_str(&mut self, s: &str) {
56//!         self.0.as_mut_array().for_each(|x: &mut String| x.push_str(s));
57//!     }
58//! }
59//! ```
60//!
61
62use self::traits::*;
63
64/// An extension trait for working with fixed-length arrays.
65///
66/// Use it with
67/// ```rust
68/// use arraytools::ArrayTools;
69/// ```
70///
71/// For an overview, see the [crate-level documentation](index.html).
72///
73/// (This trait is sealed; you are not allowed to implement it yourself.)
74pub trait ArrayTools: Sized + Sealed {
75    /// The type of the elements in this array
76    ///
77    /// ```rust
78    /// # type T = usize;
79    /// # const N: usize = 1;
80    /// use arraytools::ArrayTools;
81    ///
82    /// # fn _foo() where
83    /// [T; N]: ArrayTools<Element = T>
84    /// # {}
85    /// ```
86    type Element;
87
88    /// The number of the elements in this array
89    ///
90    /// ```rust
91    /// # type T = usize;
92    /// # const N: usize = 1;
93    /// use arraytools::ArrayTools;
94    ///
95    /// assert_eq!(<[T; N] as ArrayTools>::LEN, N);
96    /// ```
97    const LEN: usize;
98
99    /// Extracts a slice containing the entire array.
100    ///
101    /// ```rust
102    /// # type T = usize;
103    /// # const N: usize = 1;
104    /// use arraytools::ArrayTools;
105    ///
106    /// let array: [i32; 5] = [1, 2, 3, 4, 5];
107    /// let slice: &[i32] = array.as_slice();
108    /// assert_eq!(slice.len(), 5);
109    /// ```
110    fn as_slice(&self) -> &[Self::Element];
111
112    /// Extracts a mutable slice containing the entire array.
113    ///
114    /// ```rust
115    /// # type T = usize;
116    /// # const N: usize = 1;
117    /// use arraytools::ArrayTools;
118    ///
119    /// let mut array: [i32; 5] = [1, 2, 3, 4, 5];
120    /// let slice: &mut [i32] = array.as_mut_slice();
121    /// assert_eq!(slice.len(), 5);
122    /// ```
123    fn as_mut_slice(&mut self) -> &mut [Self::Element];
124
125    /// The homogeneous tuple type equivalent to this array type.
126    ///
127    /// ```rust
128    /// # type T = usize;
129    /// use arraytools::ArrayTools;
130    ///
131    /// # fn _foo() where
132    /// [T; 4]: ArrayTools<Tuple = (T, T, T, T)>
133    /// # {}
134    /// ```
135    type Tuple;
136
137    /// Converts a homogeneous tuple into the equivalent array.
138    ///
139    /// Type: `(T, T, ..., T) -> [T; N]`
140    ///
141    /// ```rust
142    /// use arraytools::ArrayTools;
143    ///
144    /// assert_eq!(<[_; 3]>::from_tuple((1, 2, 3)), [1, 2, 3]);
145    /// ```
146    fn from_tuple(tuple: Self::Tuple) -> Self;
147
148    /// Converts this array into the equivalent homogeneous tuple.
149    ///
150    /// Type: `[T; N] -> (T, T, ..., T)`
151    ///
152    /// ```rust
153    /// use arraytools::ArrayTools;
154    ///
155    /// assert_eq!([1, 2, 3].into_tuple(), (1, 2, 3));
156    /// ```
157    fn into_tuple(self) -> Self::Tuple;
158
159    /// Builds an array by calling the provided function.
160    ///
161    /// Type: `F -> [T; N]`
162    /// - when `N <= 1` this requires `F: FnOnce() -> T`
163    /// - when `N > 1` this requires `F: FnMut() -> T`
164    ///
165    /// ```rust
166    /// use arraytools::ArrayTools;
167    ///
168    /// let mut x = 1;
169    /// let array: [_; 5] = ArrayTools::generate(|| { x *= 2; x });
170    /// assert_eq!(array, [2, 4, 8, 16, 32]);
171    /// ```
172    fn generate<F>(f: F) -> Self
173        where Self: ArrayGenerate<F>
174    {
175        ArrayGenerate::generate(f)
176    }
177
178    /// Builds an array by cloning the provided value.
179    ///
180    /// Type: `T -> [T; N]`
181    ///
182    /// ```rust
183    /// use arraytools::ArrayTools;
184    ///
185    /// let mut v = Vec::with_capacity(10);
186    /// v.push(42);
187    /// let array: [_; 5] = ArrayTools::repeat(v);
188    /// assert_eq!(array, [[42], [42], [42], [42], [42]]);
189    /// assert_eq!(array[3].capacity(), 1);
190    /// assert_eq!(array[4].capacity(), 10); // The last one is moved
191    /// ```
192    fn repeat<T: Clone>(x: T) -> Self
193        where Self: ArrayRepeat<T>
194    {
195        ArrayRepeat::repeat(x)
196    }
197
198    /// Builds an array containing a prefix of the provided iterator,
199    /// or returns `None` if it didn't contain sufficient items.
200    ///
201    /// Type: `impl IntoIterator<Item = T> -> Option<[T; N]>`
202    ///
203    /// ```rust
204    /// use arraytools::ArrayTools;
205    ///
206    /// assert_eq!(<[i16; 4]>::from_iter(1..), Some([1, 2, 3, 4]));
207    ///
208    /// assert_eq!(<[_; 4]>::from_iter(1..4), None);
209    /// assert_eq!(<[_; 4]>::from_iter(1..5), Some([1, 2, 3, 4]));
210    /// assert_eq!(<[_; 4]>::from_iter(1..6), Some([1, 2, 3, 4]));
211    ///
212    /// assert_eq!(<[u8; 1]>::from_iter(Some(1)), Some([1]));
213    /// assert_eq!(<[u8; 1]>::from_iter(None), None);
214    /// ```
215    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    /// Builds the array `[0, 1, 2, ..., LEN-1]`.
222    ///
223    /// Type: `() -> [usize; N]`
224    ///
225    /// ```rust
226    /// use arraytools::ArrayTools;
227    ///
228    /// let array: [_; 5] = ArrayTools::indices();
229    /// assert_eq!(array, [0, 1, 2, 3, 4]);
230    /// ```
231    fn indices() -> Self
232        where Self: ArrayIndices
233    {
234        ArrayIndices::indices()
235    }
236
237    /// Builds a new array by applying the provided function to each element of this array.
238    ///
239    /// Type: `([T; N], F) -> [U; N]`
240    /// - when `N <= 1` this requires `F: FnOnce(T) -> U`
241    /// - when `N > 1` this requires `F: FnMut(T) -> U`
242    ///
243    /// ```rust
244    /// use arraytools::ArrayTools;
245    ///
246    /// assert_eq!([1, 10, 100].map(|x| x + 10), [11, 20, 110]);
247    /// ```
248    #[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    /// Runs the provided function on each element of this array.
256    ///
257    /// Type: `([T; N], F) -> ()`
258    /// - when `N <= 1` this requires `F: FnOnce(T) -> ()`
259    /// - when `N > 1` this requires `F: FnMut(T) -> ()`
260    ///
261    /// ```rust
262    /// use arraytools::ArrayTools;
263    ///
264    /// let mut array = [1, 10, 100];
265    /// array.as_mut_array().for_each(|x: &mut u8| *x += 10);
266    /// assert_eq!(array, [11, 20, 110]);
267    /// ```
268    fn for_each<F>(self, f: F)
269        where Self: ArrayMap<F, OutputElement = ()>
270    {
271        ArrayMap::map(self, f);
272    }
273
274    /// Combines two equal-length arrays into an array of tuples.
275    ///
276    /// Type: `([T; N], [U; N]) -> [(T, U); N]`
277    ///
278    /// ```rust
279    /// use arraytools::ArrayTools;
280    ///
281    /// assert_eq!([10, 20, 30].zip([1.0, 2.0, 3.0]), [(10, 1.0), (20, 2.0), (30, 3.0)]);
282    /// ```
283    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    /// Combines two equal-length arrays using the provided function.
290    ///
291    /// Type: `([T; N], [U; N], F) -> [V; N]`
292    /// - when `N <= 1` this requires `F: FnOnce(T, U) -> V`
293    /// - when `N > 1` this requires `F: FnMut(T, U) -> V`
294    ///
295    /// ```rust
296    /// use arraytools::ArrayTools;
297    ///
298    /// assert_eq!([10, 20, 30].zip_with([3, 2, 1], std::ops::Add::add), [13, 22, 31]);
299    /// ```
300    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    /// Builds an array of references to the elements of this array.
307    ///
308    /// Type: `&'a [T; N] -> [&'a T; N]`
309    ///
310    /// ```rust
311    /// use arraytools::ArrayTools;
312    ///
313    /// let array = &[1, 2, 3, 4, 5];
314    /// assert_eq!(array.as_ref_array(), [&1, &2, &3, &4, &5]);
315    /// ```
316    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    /// Builds an array of mutable references to the elements of this array.
323    ///
324    /// Type: `&'a mut [T; N] -> [&'a mut T; N]`
325    ///
326    /// ```rust
327    /// use arraytools::ArrayTools;
328    ///
329    /// let array = &mut [1, 2, 3];
330    /// assert_eq!(array.as_ref_array(), [&mut 1, &mut 2, &mut 3]);
331    /// ```
332    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    /// Appends an item to this array, returning the new array
339    ///
340    /// Type: `([T; N], T) -> [T; N+1]`
341    ///
342    /// ```rust
343    /// use arraytools::ArrayTools;
344    ///
345    /// assert_eq!([1, 2].push_back(10), [1, 2, 10]);
346    /// ```
347    #[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    /// Prepends an item to this array, returning the new array
355    ///
356    /// Type: `([T; N], T) -> [T; N+1]`
357    ///
358    /// ```rust
359    /// use arraytools::ArrayTools;
360    ///
361    /// assert_eq!([1, 2].push_front(10), [10, 1, 2]);
362    /// ```
363    #[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    /// Splits the last item off from this array, returning a tuple of
371    /// an array of the other elements and the split-off item.
372    ///
373    /// Type: `[T; N+1] -> ([T; N], T)`
374    ///
375    /// ```rust
376    /// use arraytools::ArrayTools;
377    ///
378    /// assert_eq!([1, 2, 3].pop_back(), ([1, 2], 3));
379    /// ```
380    #[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    /// Splits the first item off from this array, returning a tuple of
388    /// an array of the other elements and the split-off item.
389    ///
390    /// Type: `[T; N+1] -> ([T; N], T)`
391    ///
392    /// ```rust
393    /// use arraytools::ArrayTools;
394    ///
395    /// assert_eq!([1, 2, 3].pop_front(), ([2, 3], 1));
396    /// ```
397    #[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    // <https://play.rust-lang.org/?gist=10a054305dfabf05f0c652e2df75fdcc>
594    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}