sequence.rs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. //! Useful traits for manipulating sequences of data stored in `GenericArray`s
  2. use super::*;
  3. use core::ops::{Add, Sub};
  4. use core::mem::MaybeUninit;
  5. use core::ptr;
  6. use typenum::operator_aliases::*;
  7. /// Defines some sequence with an associated length and iteration capabilities.
  8. ///
  9. /// This is useful for passing N-length generic arrays as generics.
  10. pub unsafe trait GenericSequence<T>: Sized + IntoIterator {
  11. /// `GenericArray` associated length
  12. type Length: ArrayLength<T>;
  13. /// Concrete sequence type used in conjuction with reference implementations of `GenericSequence`
  14. type Sequence: GenericSequence<T, Length = Self::Length> + FromIterator<T>;
  15. /// Initializes a new sequence instance using the given function.
  16. ///
  17. /// If the generator function panics while initializing the sequence,
  18. /// any already initialized elements will be dropped.
  19. fn generate<F>(f: F) -> Self::Sequence
  20. where
  21. F: FnMut(usize) -> T;
  22. #[doc(hidden)]
  23. fn inverted_zip<B, U, F>(
  24. self,
  25. lhs: GenericArray<B, Self::Length>,
  26. mut f: F,
  27. ) -> MappedSequence<GenericArray<B, Self::Length>, B, U>
  28. where
  29. GenericArray<B, Self::Length>: GenericSequence<B, Length = Self::Length>
  30. + MappedGenericSequence<B, U>,
  31. Self: MappedGenericSequence<T, U>,
  32. Self::Length: ArrayLength<B> + ArrayLength<U>,
  33. F: FnMut(B, Self::Item) -> U,
  34. {
  35. unsafe {
  36. let mut left = ArrayConsumer::new(lhs);
  37. let (left_array_iter, left_position) = left.iter_position();
  38. FromIterator::from_iter(left_array_iter.zip(self.into_iter()).map(
  39. |(l, right_value)| {
  40. let left_value = ptr::read(l);
  41. *left_position += 1;
  42. f(left_value, right_value)
  43. },
  44. ))
  45. }
  46. }
  47. #[doc(hidden)]
  48. fn inverted_zip2<B, Lhs, U, F>(self, lhs: Lhs, mut f: F) -> MappedSequence<Lhs, B, U>
  49. where
  50. Lhs: GenericSequence<B, Length = Self::Length> + MappedGenericSequence<B, U>,
  51. Self: MappedGenericSequence<T, U>,
  52. Self::Length: ArrayLength<B> + ArrayLength<U>,
  53. F: FnMut(Lhs::Item, Self::Item) -> U,
  54. {
  55. FromIterator::from_iter(lhs.into_iter().zip(self.into_iter()).map(|(l, r)| f(l, r)))
  56. }
  57. }
  58. /// Accessor for `GenericSequence` item type, which is really `IntoIterator::Item`
  59. ///
  60. /// For deeply nested generic mapped sequence types, like shown in `tests/generics.rs`,
  61. /// this can be useful for keeping things organized.
  62. pub type SequenceItem<T> = <T as IntoIterator>::Item;
  63. unsafe impl<'a, T: 'a, S: GenericSequence<T>> GenericSequence<T> for &'a S
  64. where
  65. &'a S: IntoIterator,
  66. {
  67. type Length = S::Length;
  68. type Sequence = S::Sequence;
  69. #[inline]
  70. fn generate<F>(f: F) -> Self::Sequence
  71. where
  72. F: FnMut(usize) -> T,
  73. {
  74. S::generate(f)
  75. }
  76. }
  77. unsafe impl<'a, T: 'a, S: GenericSequence<T>> GenericSequence<T> for &'a mut S
  78. where
  79. &'a mut S: IntoIterator,
  80. {
  81. type Length = S::Length;
  82. type Sequence = S::Sequence;
  83. #[inline]
  84. fn generate<F>(f: F) -> Self::Sequence
  85. where
  86. F: FnMut(usize) -> T,
  87. {
  88. S::generate(f)
  89. }
  90. }
  91. /// Defines any `GenericSequence` which can be lengthened or extended by appending
  92. /// or prepending an element to it.
  93. ///
  94. /// Any lengthened sequence can be shortened back to the original using `pop_front` or `pop_back`
  95. pub unsafe trait Lengthen<T>: Sized + GenericSequence<T> {
  96. /// `GenericSequence` that has one more element than `Self`
  97. type Longer: Shorten<T, Shorter = Self>;
  98. /// Returns a new array with the given element appended to the end of it.
  99. ///
  100. /// Example:
  101. ///
  102. /// ```rust
  103. /// # use generic_array::{arr, sequence::Lengthen};
  104. /// # fn main() {
  105. /// let a = arr![i32; 1, 2, 3];
  106. ///
  107. /// let b = a.append(4);
  108. ///
  109. /// assert_eq!(b, arr![i32; 1, 2, 3, 4]);
  110. /// # }
  111. /// ```
  112. fn append(self, last: T) -> Self::Longer;
  113. /// Returns a new array with the given element prepended to the front of it.
  114. ///
  115. /// Example:
  116. ///
  117. /// ```rust
  118. /// # use generic_array::{arr, sequence::Lengthen};
  119. /// # fn main() {
  120. /// let a = arr![i32; 1, 2, 3];
  121. ///
  122. /// let b = a.prepend(4);
  123. ///
  124. /// assert_eq!(b, arr![i32; 4, 1, 2, 3]);
  125. /// # }
  126. /// ```
  127. fn prepend(self, first: T) -> Self::Longer;
  128. }
  129. /// Defines a `GenericSequence` which can be shortened by removing the first or last element from it.
  130. ///
  131. /// Additionally, any shortened sequence can be lengthened by
  132. /// appending or prepending an element to it.
  133. pub unsafe trait Shorten<T>: Sized + GenericSequence<T> {
  134. /// `GenericSequence` that has one less element than `Self`
  135. type Shorter: Lengthen<T, Longer = Self>;
  136. /// Returns a new array without the last element, and the last element.
  137. ///
  138. /// Example:
  139. ///
  140. /// ```rust
  141. /// # use generic_array::{arr, sequence::Shorten};
  142. /// # fn main() {
  143. /// let a = arr![i32; 1, 2, 3, 4];
  144. ///
  145. /// let (init, last) = a.pop_back();
  146. ///
  147. /// assert_eq!(init, arr![i32; 1, 2, 3]);
  148. /// assert_eq!(last, 4);
  149. /// # }
  150. /// ```
  151. fn pop_back(self) -> (Self::Shorter, T);
  152. /// Returns a new array without the first element, and the first element.
  153. /// Example:
  154. ///
  155. /// ```rust
  156. /// # use generic_array::{arr, sequence::Shorten};
  157. /// # fn main() {
  158. /// let a = arr![i32; 1, 2, 3, 4];
  159. ///
  160. /// let (head, tail) = a.pop_front();
  161. ///
  162. /// assert_eq!(head, 1);
  163. /// assert_eq!(tail, arr![i32; 2, 3, 4]);
  164. /// # }
  165. /// ```
  166. fn pop_front(self) -> (T, Self::Shorter);
  167. }
  168. unsafe impl<T, N: ArrayLength<T>> Lengthen<T> for GenericArray<T, N>
  169. where
  170. N: Add<B1>,
  171. Add1<N>: ArrayLength<T>,
  172. Add1<N>: Sub<B1, Output = N>,
  173. Sub1<Add1<N>>: ArrayLength<T>,
  174. {
  175. type Longer = GenericArray<T, Add1<N>>;
  176. fn append(self, last: T) -> Self::Longer {
  177. let mut longer: MaybeUninit<Self::Longer> = MaybeUninit::uninit();
  178. // Note this is *mut Self, so add(1) increments by the whole array
  179. let out_ptr = longer.as_mut_ptr() as *mut Self;
  180. unsafe {
  181. // write self first
  182. ptr::write(out_ptr, self);
  183. // increment past self, then write the last
  184. ptr::write(out_ptr.add(1) as *mut T, last);
  185. longer.assume_init()
  186. }
  187. }
  188. fn prepend(self, first: T) -> Self::Longer {
  189. let mut longer: MaybeUninit<Self::Longer> = MaybeUninit::uninit();
  190. // Note this is *mut T, so add(1) increments by a single T
  191. let out_ptr = longer.as_mut_ptr() as *mut T;
  192. unsafe {
  193. // write the first at the start
  194. ptr::write(out_ptr, first);
  195. // increment past the first, then write self
  196. ptr::write(out_ptr.add(1) as *mut Self, self);
  197. longer.assume_init()
  198. }
  199. }
  200. }
  201. unsafe impl<T, N: ArrayLength<T>> Shorten<T> for GenericArray<T, N>
  202. where
  203. N: Sub<B1>,
  204. Sub1<N>: ArrayLength<T>,
  205. Sub1<N>: Add<B1, Output = N>,
  206. Add1<Sub1<N>>: ArrayLength<T>,
  207. {
  208. type Shorter = GenericArray<T, Sub1<N>>;
  209. fn pop_back(self) -> (Self::Shorter, T) {
  210. let whole = ManuallyDrop::new(self);
  211. unsafe {
  212. let init = ptr::read(whole.as_ptr() as _);
  213. let last = ptr::read(whole.as_ptr().add(Sub1::<N>::USIZE) as _);
  214. (init, last)
  215. }
  216. }
  217. fn pop_front(self) -> (T, Self::Shorter) {
  218. // ensure this doesn't get dropped
  219. let whole = ManuallyDrop::new(self);
  220. unsafe {
  221. let head = ptr::read(whole.as_ptr() as _);
  222. let tail = ptr::read(whole.as_ptr().offset(1) as _);
  223. (head, tail)
  224. }
  225. }
  226. }
  227. /// Defines a `GenericSequence` that can be split into two parts at a given pivot index.
  228. pub unsafe trait Split<T, K>: GenericSequence<T>
  229. where
  230. K: ArrayLength<T>,
  231. {
  232. /// First part of the resulting split array
  233. type First: GenericSequence<T>;
  234. /// Second part of the resulting split array
  235. type Second: GenericSequence<T>;
  236. /// Splits an array at the given index, returning the separate parts of the array.
  237. fn split(self) -> (Self::First, Self::Second);
  238. }
  239. unsafe impl<T, N, K> Split<T, K> for GenericArray<T, N>
  240. where
  241. N: ArrayLength<T>,
  242. K: ArrayLength<T>,
  243. N: Sub<K>,
  244. Diff<N, K>: ArrayLength<T>,
  245. {
  246. type First = GenericArray<T, K>;
  247. type Second = GenericArray<T, Diff<N, K>>;
  248. fn split(self) -> (Self::First, Self::Second) {
  249. unsafe {
  250. // ensure this doesn't get dropped
  251. let whole = ManuallyDrop::new(self);
  252. let head = ptr::read(whole.as_ptr() as *const _);
  253. let tail = ptr::read(whole.as_ptr().add(K::USIZE) as *const _);
  254. (head, tail)
  255. }
  256. }
  257. }
  258. unsafe impl<'a, T, N, K> Split<T, K> for &'a GenericArray<T, N>
  259. where
  260. N: ArrayLength<T>,
  261. K: ArrayLength<T> + 'static,
  262. N: Sub<K>,
  263. Diff<N, K>: ArrayLength<T>,
  264. {
  265. type First = &'a GenericArray<T, K>;
  266. type Second = &'a GenericArray<T, Diff<N, K>>;
  267. fn split(self) -> (Self::First, Self::Second) {
  268. unsafe {
  269. let ptr_to_first: *const T = self.as_ptr();
  270. let head = &*(ptr_to_first as *const _);
  271. let tail = &*(ptr_to_first.add(K::USIZE) as *const _);
  272. (head, tail)
  273. }
  274. }
  275. }
  276. unsafe impl<'a, T, N, K> Split<T, K> for &'a mut GenericArray<T, N>
  277. where
  278. N: ArrayLength<T>,
  279. K: ArrayLength<T> + 'static,
  280. N: Sub<K>,
  281. Diff<N, K>: ArrayLength<T>,
  282. {
  283. type First = &'a mut GenericArray<T, K>;
  284. type Second = &'a mut GenericArray<T, Diff<N, K>>;
  285. fn split(self) -> (Self::First, Self::Second) {
  286. unsafe {
  287. let ptr_to_first: *mut T = self.as_mut_ptr();
  288. let head = &mut *(ptr_to_first as *mut _);
  289. let tail = &mut *(ptr_to_first.add(K::USIZE) as *mut _);
  290. (head, tail)
  291. }
  292. }
  293. }
  294. /// Defines `GenericSequence`s which can be joined together, forming a larger array.
  295. pub unsafe trait Concat<T, M>: GenericSequence<T>
  296. where
  297. M: ArrayLength<T>,
  298. {
  299. /// Sequence to be concatenated with `self`
  300. type Rest: GenericSequence<T, Length = M>;
  301. /// Resulting sequence formed by the concatenation.
  302. type Output: GenericSequence<T>;
  303. /// Concatenate, or join, two sequences.
  304. fn concat(self, rest: Self::Rest) -> Self::Output;
  305. }
  306. unsafe impl<T, N, M> Concat<T, M> for GenericArray<T, N>
  307. where
  308. N: ArrayLength<T> + Add<M>,
  309. M: ArrayLength<T>,
  310. Sum<N, M>: ArrayLength<T>,
  311. {
  312. type Rest = GenericArray<T, M>;
  313. type Output = GenericArray<T, Sum<N, M>>;
  314. fn concat(self, rest: Self::Rest) -> Self::Output {
  315. let mut output: MaybeUninit<Self::Output> = MaybeUninit::uninit();
  316. let out_ptr = output.as_mut_ptr() as *mut Self;
  317. unsafe {
  318. // write all of self to the pointer
  319. ptr::write(out_ptr, self);
  320. // increment past self, then write the rest
  321. ptr::write(out_ptr.add(1) as *mut _, rest);
  322. output.assume_init()
  323. }
  324. }
  325. }