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