1
+ //! Functional programming with generic sequences
2
+
3
+ use core:: iter:: FromIterator ;
4
+
5
+ use super :: ArrayLength ;
6
+ use sequence:: * ;
7
+
8
+ /// Defines the relationship between one generic sequence and another,
9
+ /// for operations such as `map` and `zip`.
10
+ pub unsafe trait MappedGenericSequence < T , U > : GenericSequence < T >
11
+ where
12
+ Self :: Length : ArrayLength < U > ,
13
+ {
14
+ /// Mapped sequence type
15
+ type Mapped : GenericSequence < U , Length =Self :: Length > ;
16
+ }
17
+
18
+ unsafe impl < ' a , T , U , S : MappedGenericSequence < T , U > > MappedGenericSequence < T , U > for & ' a S
19
+ where
20
+ & ' a S : GenericSequence < T > ,
21
+ S : GenericSequence < T , Length =<& ' a S as GenericSequence < T > >:: Length > ,
22
+ <S as GenericSequence < T > >:: Length : ArrayLength < U > ,
23
+ {
24
+ type Mapped = <S as MappedGenericSequence < T , U > >:: Mapped ;
25
+ }
26
+
27
+ /// Accessor type for a mapped generic sequence
28
+ pub type MappedSequence < S , T , U > = <<S as MappedGenericSequence < T , U > >:: Mapped as GenericSequence < U > >:: Sequence ;
29
+
30
+ /// Defines functional programming methods for generic sequences
31
+ pub unsafe trait FunctionalSequence < T > : GenericSequence < T > {
32
+ /// Maps a `GenericSequence` to another `GenericSequence`.
33
+ ///
34
+ /// If the mapping function panics, any already initialized elements in the new sequence
35
+ /// will be dropped, AND any unused elements in the source sequence will also be dropped.
36
+ fn map < U , F > ( self , f : F ) -> MappedSequence < Self , T , U >
37
+ where
38
+ Self : MappedGenericSequence < T , U > ,
39
+ Self :: Length : ArrayLength < U > ,
40
+ F : Fn ( SequenceItem < Self > ) -> U ,
41
+ {
42
+ FromIterator :: from_iter ( self . into_iter ( ) . map ( f) )
43
+ }
44
+
45
+ /// Combines two `GenericSequence` instances and iterates through both of them,
46
+ /// initializing a new `GenericSequence` with the result of the zipped mapping function.
47
+ ///
48
+ /// If the mapping function panics, any already initialized elements in the new sequence
49
+ /// will be dropped, AND any unused elements in the source sequences will also be dropped.
50
+ fn zip < B , Rhs , U , F > ( self , rhs : Rhs , f : F ) -> MappedSequence < Self , T , U >
51
+ where
52
+ Self : MappedGenericSequence < T , U > ,
53
+ Self :: Length : ArrayLength < B > + ArrayLength < U > ,
54
+ Rhs : GenericSequence < B > ,
55
+ F : Fn ( SequenceItem < Self > , SequenceItem < Rhs > ) -> U ,
56
+ {
57
+ FromIterator :: from_iter ( self . into_iter ( ) . zip ( rhs. into_iter ( ) ) . map ( |( l, r) | f ( l, r) ) )
58
+ }
59
+ }
60
+
61
+ unsafe impl < ' a , T , S : GenericSequence < T > > FunctionalSequence < T > for & ' a S
62
+ where
63
+ & ' a S : GenericSequence < T > ,
64
+ { }
65
+
66
+ unsafe impl < ' a , T , S : GenericSequence < T > > FunctionalSequence < T > for & ' a mut S
67
+ where
68
+ & ' a mut S : GenericSequence < T > ,
69
+ { }
0 commit comments