]> git.proxmox.com Git - rustc.git/blob - vendor/generic-array-0.12.3/tests/generics.rs
New upstream version 1.48.0~beta.8+dfsg1
[rustc.git] / vendor / generic-array-0.12.3 / tests / generics.rs
1 #![recursion_limit = "128"]
2
3 #[macro_use]
4 extern crate generic_array;
5
6 use generic_array::typenum::consts::U4;
7
8 use std::fmt::Debug;
9 use std::ops::Add;
10
11 use generic_array::{GenericArray, ArrayLength};
12 use generic_array::sequence::*;
13 use generic_array::functional::*;
14
15 /// Example function using generics to pass N-length sequences and map them
16 pub fn generic_map<S>(s: S)
17 where
18 S: FunctionalSequence<i32>, // `.map`
19 S::Item: Add<i32, Output = i32>, // `x + 1`
20 S: MappedGenericSequence<i32, i32>, // `i32` -> `i32`
21 MappedSequence<S, i32, i32>: Debug, // println!
22 {
23 let a = s.map(|x| x + 1);
24
25 println!("{:?}", a);
26 }
27
28 /// Complex example function using generics to pass N-length sequences, zip them, and then map that result.
29 ///
30 /// If used with `GenericArray` specifically this isn't necessary
31 pub fn generic_sequence_zip_sum<A, B>(a: A, b: B) -> i32
32 where
33 A: FunctionalSequence<i32>, // `.zip`
34 B: FunctionalSequence<i32, Length = A::Length>, // `.zip`
35 A: MappedGenericSequence<i32, i32>, // `i32` -> `i32`
36 B: MappedGenericSequence<i32, i32, Mapped = MappedSequence<A, i32, i32>>, // `i32` -> `i32`, prove A and B can map to the same output
37 A::Item: Add<B::Item, Output = i32>, // `l + r`
38 MappedSequence<A, i32, i32>: MappedGenericSequence<i32, i32> + FunctionalSequence<i32>, // `.map`
39 SequenceItem<MappedSequence<A, i32, i32>>: Add<i32, Output=i32>, // `x + 1`
40 MappedSequence<MappedSequence<A, i32, i32>, i32, i32>: Debug, // `println!`
41 MappedSequence<MappedSequence<A, i32, i32>, i32, i32>: FunctionalSequence<i32>, // `.fold`
42 SequenceItem<MappedSequence<MappedSequence<A, i32, i32>, i32, i32>>: Add<i32, Output=i32> // `x + a`, note the order
43 {
44 let c = a.zip(b, |l, r| l + r).map(|x| x + 1);
45
46 println!("{:?}", c);
47
48 c.fold(0, |a, x| x + a)
49 }
50
51 /// Super-simple fixed-length i32 `GenericArray`s
52 pub fn generic_array_plain_zip_sum(a: GenericArray<i32, U4>, b: GenericArray<i32, U4>) -> i32 {
53 a.zip(b, |l, r| l + r).map(|x| x + 1).fold(0, |a, x| x + a)
54 }
55
56 pub fn generic_array_variable_length_zip_sum<N>(a: GenericArray<i32, N>, b: GenericArray<i32, N>) -> i32
57 where
58 N: ArrayLength<i32>,
59 {
60 a.zip(b, |l, r| l + r).map(|x| x + 1).fold(0, |a, x| x + a)
61 }
62
63 pub fn generic_array_same_type_variable_length_zip_sum<T, N>(a: GenericArray<T, N>, b: GenericArray<T, N>) -> i32
64 where
65 N: ArrayLength<T> + ArrayLength<<T as Add<T>>::Output>,
66 T: Add<T, Output=i32>,
67 {
68 a.zip(b, |l, r| l + r).map(|x| x + 1).fold(0, |a, x| x + a)
69 }
70
71 /// Complex example using fully generic `GenericArray`s with the same length.
72 ///
73 /// It's mostly just the repeated `Add` traits, which would be present in other systems anyway.
74 pub fn generic_array_zip_sum<A, B, N: ArrayLength<A> + ArrayLength<B>>(a: GenericArray<A, N>, b: GenericArray<B, N>) -> i32
75 where
76 A: Add<B>,
77 N: ArrayLength<<A as Add<B>>::Output> +
78 ArrayLength<<<A as Add<B>>::Output as Add<i32>>::Output>,
79 <A as Add<B>>::Output: Add<i32>,
80 <<A as Add<B>>::Output as Add<i32>>::Output: Add<i32, Output=i32>,
81 {
82 a.zip(b, |l, r| l + r).map(|x| x + 1).fold(0, |a, x| x + a)
83 }
84
85 #[test]
86 fn test_generics() {
87 generic_map(arr![i32; 1, 2, 3, 4]);
88
89 assert_eq!(generic_sequence_zip_sum(arr![i32; 1, 2, 3, 4], arr![i32; 2, 3, 4, 5]), 28);
90
91 assert_eq!(generic_array_plain_zip_sum(arr![i32; 1, 2, 3, 4], arr![i32; 2, 3, 4, 5]), 28);
92
93 assert_eq!(generic_array_variable_length_zip_sum(arr![i32; 1, 2, 3, 4], arr![i32; 2, 3, 4, 5]), 28);
94
95 assert_eq!(generic_array_same_type_variable_length_zip_sum(arr![i32; 1, 2, 3, 4], arr![i32; 2, 3, 4, 5]), 28);
96
97 assert_eq!(generic_array_zip_sum(arr![i32; 1, 2, 3, 4], arr![i32; 2, 3, 4, 5]), 28);
98 }