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
+ unsafe impl < ' a , T , U , S : MappedGenericSequence < T , U > > MappedGenericSequence < T , U > for & ' a mut S
28
+ where
29
+ & ' a mut S : GenericSequence < T > ,
30
+ S : GenericSequence < T , Length =<& ' a mut S as GenericSequence < T > >:: Length > ,
31
+ <S as GenericSequence < T > >:: Length : ArrayLength < U > ,
32
+ {
33
+ type Mapped = <S as MappedGenericSequence < T , U > >:: Mapped ;
34
+ }
35
+
36
+ /// Accessor type for a mapped generic sequence
37
+ pub type MappedSequence < S , T , U > = <<S as MappedGenericSequence < T , U > >:: Mapped as GenericSequence < U > >:: Sequence ;
38
+
39
+ /// Defines functional programming methods for generic sequences
40
+ pub unsafe trait FunctionalSequence < T > : GenericSequence < T > {
41
+ /// Maps a `GenericSequence` to another `GenericSequence`.
42
+ ///
43
+ /// If the mapping function panics, any already initialized elements in the new sequence
44
+ /// will be dropped, AND any unused elements in the source sequence will also be dropped.
45
+ fn map < U , F > ( self , f : F ) -> MappedSequence < Self , T , U >
46
+ where
47
+ Self : MappedGenericSequence < T , U > ,
48
+ Self :: Length : ArrayLength < U > ,
49
+ F : FnMut ( Self :: Item ) -> U ,
50
+ {
51
+ FromIterator :: from_iter ( self . into_iter ( ) . map ( f) )
52
+ }
53
+
54
+ /// Combines two `GenericSequence` instances and iterates through both of them,
55
+ /// initializing a new `GenericSequence` with the result of the zipped mapping function.
56
+ ///
57
+ /// If the mapping function panics, any already initialized elements in the new sequence
58
+ /// will be dropped, AND any unused elements in the source sequences will also be dropped.
59
+ #[ inline]
60
+ fn zip < B , Rhs , U , F > ( self , rhs : Rhs , f : F ) -> MappedSequence < Self , T , U >
61
+ where
62
+ Self : MappedGenericSequence < T , U > ,
63
+ Rhs : MappedGenericSequence < B , U , Mapped =MappedSequence < Self , T , U > > ,
64
+ Self :: Length : ArrayLength < B > + ArrayLength < U > ,
65
+ Rhs : GenericSequence < B , Length =Self :: Length > ,
66
+ F : FnMut ( Self :: Item , Rhs :: Item ) -> U ,
67
+ {
68
+ rhs. inverted_zip2 ( self , f)
69
+ }
70
+
71
+ /// Folds (or reduces) a sequence of data into a single value.
72
+ ///
73
+ /// If the fold function panics, any unused elements will be dropped.
74
+ fn fold < U , F > ( self , init : U , f : F ) -> U
75
+ where
76
+ F : FnMut ( U , Self :: Item ) -> U ,
77
+ {
78
+ self . into_iter ( ) . fold ( init, f)
79
+ }
80
+ }
81
+
82
+ unsafe impl < ' a , T , S : GenericSequence < T > > FunctionalSequence < T > for & ' a S
83
+ where
84
+ & ' a S : GenericSequence < T > ,
85
+ { }
86
+
87
+ unsafe impl < ' a , T , S : GenericSequence < T > > FunctionalSequence < T > for & ' a mut S
88
+ where
89
+ & ' a mut S : GenericSequence < T > ,
90
+ { }
0 commit comments