1 //! Functional programming with generic sequences 2 //! 3 //! Please see `tests/generics.rs` for examples of how to best use these in your generic functions. 4 5 use super::ArrayLength; 6 use core::iter::FromIterator; 7 8 use crate::sequence::*; 9 10 /// Defines the relationship between one generic sequence and another, 11 /// for operations such as `map` and `zip`. 12 pub unsafe trait MappedGenericSequence<T, U>: GenericSequence<T> 13 where 14 Self::Length: ArrayLength<U>, 15 { 16 /// Mapped sequence type 17 type Mapped: GenericSequence<U, Length = Self::Length>; 18 } 19 20 unsafe impl<'a, T, U, S: MappedGenericSequence<T, U>> MappedGenericSequence<T, U> for &'a S 21 where 22 &'a S: GenericSequence<T>, 23 S: GenericSequence<T, Length = <&'a S as GenericSequence<T>>::Length>, 24 <S as GenericSequence<T>>::Length: ArrayLength<U>, 25 { 26 type Mapped = <S as MappedGenericSequence<T, U>>::Mapped; 27 } 28 29 unsafe impl<'a, T, U, S: MappedGenericSequence<T, U>> MappedGenericSequence<T, U> for &'a mut S 30 where 31 &'a mut S: GenericSequence<T>, 32 S: GenericSequence<T, Length = <&'a mut S as GenericSequence<T>>::Length>, 33 <S as GenericSequence<T>>::Length: ArrayLength<U>, 34 { 35 type Mapped = <S as MappedGenericSequence<T, U>>::Mapped; 36 } 37 38 /// Accessor type for a mapped generic sequence 39 pub type MappedSequence<S, T, U> = 40 <<S as MappedGenericSequence<T, U>>::Mapped as GenericSequence<U>>::Sequence; 41 42 /// Defines functional programming methods for generic sequences 43 pub unsafe trait FunctionalSequence<T>: GenericSequence<T> { 44 /// Maps a `GenericSequence` to another `GenericSequence`. 45 /// 46 /// If the mapping function panics, any already initialized elements in the new sequence 47 /// will be dropped, AND any unused elements in the source sequence will also be dropped. map<U, F>(self, f: F) -> MappedSequence<Self, T, U> where Self: MappedGenericSequence<T, U>, Self::Length: ArrayLength<U>, F: FnMut(Self::Item) -> U,48 fn map<U, F>(self, f: F) -> MappedSequence<Self, T, U> 49 where 50 Self: MappedGenericSequence<T, U>, 51 Self::Length: ArrayLength<U>, 52 F: FnMut(Self::Item) -> U, 53 { 54 FromIterator::from_iter(self.into_iter().map(f)) 55 } 56 57 /// Combines two `GenericSequence` instances and iterates through both of them, 58 /// initializing a new `GenericSequence` with the result of the zipped mapping function. 59 /// 60 /// If the mapping function panics, any already initialized elements in the new sequence 61 /// will be dropped, AND any unused elements in the source sequences will also be dropped. 62 #[inline] zip<B, Rhs, U, F>(self, rhs: Rhs, f: F) -> MappedSequence<Self, T, U> where Self: MappedGenericSequence<T, U>, Rhs: MappedGenericSequence<B, U, Mapped = MappedSequence<Self, T, U>>, Self::Length: ArrayLength<B> + ArrayLength<U>, Rhs: GenericSequence<B, Length = Self::Length>, F: FnMut(Self::Item, Rhs::Item) -> U,63 fn zip<B, Rhs, U, F>(self, rhs: Rhs, f: F) -> MappedSequence<Self, T, U> 64 where 65 Self: MappedGenericSequence<T, U>, 66 Rhs: MappedGenericSequence<B, U, Mapped = MappedSequence<Self, T, U>>, 67 Self::Length: ArrayLength<B> + ArrayLength<U>, 68 Rhs: GenericSequence<B, Length = Self::Length>, 69 F: FnMut(Self::Item, Rhs::Item) -> U, 70 { 71 rhs.inverted_zip2(self, f) 72 } 73 74 /// Folds (or reduces) a sequence of data into a single value. 75 /// 76 /// If the fold function panics, any unused elements will be dropped. fold<U, F>(self, init: U, f: F) -> U where F: FnMut(U, Self::Item) -> U,77 fn fold<U, F>(self, init: U, f: F) -> U 78 where 79 F: FnMut(U, Self::Item) -> U, 80 { 81 self.into_iter().fold(init, f) 82 } 83 } 84 85 unsafe impl<'a, T, S: GenericSequence<T>> FunctionalSequence<T> for &'a S 86 where 87 &'a S: GenericSequence<T>, 88 { 89 } 90 91 unsafe impl<'a, T, S: GenericSequence<T>> FunctionalSequence<T> for &'a mut S 92 where 93 &'a mut S: GenericSequence<T>, 94 { 95 } 96