]>
git.proxmox.com Git - rustc.git/blob - vendor/generic-array/src/sequence.rs
1 //! Useful traits for manipulating sequences of data stored in `GenericArray`s
4 use core
::ops
::{Add, Sub}
;
5 use core
::mem
::MaybeUninit
;
7 use typenum
::operator_aliases
::*;
9 /// Defines some sequence with an associated length and iteration capabilities.
11 /// This is useful for passing N-length generic arrays as generics.
12 pub unsafe trait GenericSequence
<T
>: Sized
+ IntoIterator
{
13 /// `GenericArray` associated length
14 type Length
: ArrayLength
<T
>;
16 /// Concrete sequence type used in conjuction with reference implementations of `GenericSequence`
17 type Sequence
: GenericSequence
<T
, Length
= Self::Length
> + FromIterator
<T
>;
19 /// Initializes a new sequence instance using the given function.
21 /// If the generator function panics while initializing the sequence,
22 /// any already initialized elements will be dropped.
23 fn generate
<F
>(f
: F
) -> Self::Sequence
28 fn inverted_zip
<B
, U
, F
>(
30 lhs
: GenericArray
<B
, Self::Length
>,
32 ) -> MappedSequence
<GenericArray
<B
, Self::Length
>, B
, U
>
34 GenericArray
<B
, Self::Length
>: GenericSequence
<B
, Length
= Self::Length
>
35 + MappedGenericSequence
<B
, U
>,
36 Self: MappedGenericSequence
<T
, U
>,
37 Self::Length
: ArrayLength
<B
> + ArrayLength
<U
>,
38 F
: FnMut(B
, Self::Item
) -> U
,
41 let mut left
= ArrayConsumer
::new(lhs
);
43 let (left_array_iter
, left_position
) = left
.iter_position();
45 FromIterator
::from_iter(left_array_iter
.zip(self.into_iter()).map(
47 let left_value
= ptr
::read(l
);
51 f(left_value
, right_value
)
58 fn inverted_zip2
<B
, Lhs
, U
, F
>(self, lhs
: Lhs
, mut f
: F
) -> MappedSequence
<Lhs
, B
, U
>
60 Lhs
: GenericSequence
<B
, Length
= Self::Length
> + MappedGenericSequence
<B
, U
>,
61 Self: MappedGenericSequence
<T
, U
>,
62 Self::Length
: ArrayLength
<B
> + ArrayLength
<U
>,
63 F
: FnMut(Lhs
::Item
, Self::Item
) -> U
,
65 FromIterator
::from_iter(lhs
.into_iter().zip(self.into_iter()).map(|(l
, r
)| f(l
, r
)))
69 /// Accessor for `GenericSequence` item type, which is really `IntoIterator::Item`
71 /// For deeply nested generic mapped sequence types, like shown in `tests/generics.rs`,
72 /// this can be useful for keeping things organized.
73 pub type SequenceItem
<T
> = <T
as IntoIterator
>::Item
;
75 unsafe impl<'a
, T
: 'a
, S
: GenericSequence
<T
>> GenericSequence
<T
> for &'a S
79 type Length
= S
::Length
;
80 type Sequence
= S
::Sequence
;
83 fn generate
<F
>(f
: F
) -> Self::Sequence
91 unsafe impl<'a
, T
: 'a
, S
: GenericSequence
<T
>> GenericSequence
<T
> for &'a
mut S
93 &'a
mut S
: IntoIterator
,
95 type Length
= S
::Length
;
96 type Sequence
= S
::Sequence
;
99 fn generate
<F
>(f
: F
) -> Self::Sequence
101 F
: FnMut(usize) -> T
,
107 /// Defines any `GenericSequence` which can be lengthened or extended by appending
108 /// or prepending an element to it.
110 /// Any lengthened sequence can be shortened back to the original using `pop_front` or `pop_back`
111 pub unsafe trait Lengthen
<T
>: Sized
+ GenericSequence
<T
> {
112 /// `GenericSequence` that has one more element than `Self`
113 type Longer
: Shorten
<T
, Shorter
= Self>;
115 /// Returns a new array with the given element appended to the end of it.
120 /// # use generic_array::{arr, sequence::Lengthen};
122 /// let a = arr![i32; 1, 2, 3];
124 /// let b = a.append(4);
126 /// assert_eq!(b, arr![i32; 1, 2, 3, 4]);
129 fn append(self, last
: T
) -> Self::Longer
;
131 /// Returns a new array with the given element prepended to the front of it.
136 /// # use generic_array::{arr, sequence::Lengthen};
138 /// let a = arr![i32; 1, 2, 3];
140 /// let b = a.prepend(4);
142 /// assert_eq!(b, arr![i32; 4, 1, 2, 3]);
145 fn prepend(self, first
: T
) -> Self::Longer
;
148 /// Defines a `GenericSequence` which can be shortened by removing the first or last element from it.
150 /// Additionally, any shortened sequence can be lengthened by
151 /// appending or prepending an element to it.
152 pub unsafe trait Shorten
<T
>: Sized
+ GenericSequence
<T
> {
153 /// `GenericSequence` that has one less element than `Self`
154 type Shorter
: Lengthen
<T
, Longer
= Self>;
156 /// Returns a new array without the last element, and the last element.
161 /// # use generic_array::{arr, sequence::Shorten};
163 /// let a = arr![i32; 1, 2, 3, 4];
165 /// let (init, last) = a.pop_back();
167 /// assert_eq!(init, arr![i32; 1, 2, 3]);
168 /// assert_eq!(last, 4);
171 fn pop_back(self) -> (Self::Shorter
, T
);
173 /// Returns a new array without the first element, and the first element.
177 /// # use generic_array::{arr, sequence::Shorten};
179 /// let a = arr![i32; 1, 2, 3, 4];
181 /// let (head, tail) = a.pop_front();
183 /// assert_eq!(head, 1);
184 /// assert_eq!(tail, arr![i32; 2, 3, 4]);
187 fn pop_front(self) -> (T
, Self::Shorter
);
190 unsafe impl<T
, N
: ArrayLength
<T
>> Lengthen
<T
> for GenericArray
<T
, N
>
193 Add1
<N
>: ArrayLength
<T
>,
194 Add1
<N
>: Sub
<B1
, Output
= N
>,
195 Sub1
<Add1
<N
>>: ArrayLength
<T
>,
197 type Longer
= GenericArray
<T
, Add1
<N
>>;
199 fn append(self, last
: T
) -> Self::Longer
{
200 let mut longer
: MaybeUninit
<Self::Longer
> = MaybeUninit
::uninit();
202 // Note this is *mut Self, so add(1) increments by the whole array
203 let out_ptr
= longer
.as_mut_ptr() as *mut Self;
207 ptr
::write(out_ptr
, self);
208 // increment past self, then write the last
209 ptr
::write(out_ptr
.add(1) as *mut T
, last
);
215 fn prepend(self, first
: T
) -> Self::Longer
{
216 let mut longer
: MaybeUninit
<Self::Longer
> = MaybeUninit
::uninit();
218 // Note this is *mut T, so add(1) increments by a single T
219 let out_ptr
= longer
.as_mut_ptr() as *mut T
;
222 // write the first at the start
223 ptr
::write(out_ptr
, first
);
224 // increment past the first, then write self
225 ptr
::write(out_ptr
.add(1) as *mut Self, self);
232 unsafe impl<T
, N
: ArrayLength
<T
>> Shorten
<T
> for GenericArray
<T
, N
>
235 Sub1
<N
>: ArrayLength
<T
>,
236 Sub1
<N
>: Add
<B1
, Output
= N
>,
237 Add1
<Sub1
<N
>>: ArrayLength
<T
>,
239 type Shorter
= GenericArray
<T
, Sub1
<N
>>;
241 fn pop_back(self) -> (Self::Shorter
, T
) {
242 let whole
= ManuallyDrop
::new(self);
245 let init
= ptr
::read(whole
.as_ptr() as _
);
246 let last
= ptr
::read(whole
.as_ptr().add(Sub1
::<N
>::USIZE
) as _
);
252 fn pop_front(self) -> (T
, Self::Shorter
) {
253 // ensure this doesn't get dropped
254 let whole
= ManuallyDrop
::new(self);
257 let head
= ptr
::read(whole
.as_ptr() as _
);
258 let tail
= ptr
::read(whole
.as_ptr().offset(1) as _
);
265 /// Defines a `GenericSequence` that can be split into two parts at a given pivot index.
266 pub unsafe trait Split
<T
, K
>: GenericSequence
<T
>
270 /// First part of the resulting split array
271 type First
: GenericSequence
<T
>;
272 /// Second part of the resulting split array
273 type Second
: GenericSequence
<T
>;
275 /// Splits an array at the given index, returning the separate parts of the array.
276 fn split(self) -> (Self::First
, Self::Second
);
279 unsafe impl<T
, N
, K
> Split
<T
, K
> for GenericArray
<T
, N
>
284 Diff
<N
, K
>: ArrayLength
<T
>,
286 type First
= GenericArray
<T
, K
>;
287 type Second
= GenericArray
<T
, Diff
<N
, K
>>;
289 fn split(self) -> (Self::First
, Self::Second
) {
291 // ensure this doesn't get dropped
292 let whole
= ManuallyDrop
::new(self);
294 let head
= ptr
::read(whole
.as_ptr() as *const _
);
295 let tail
= ptr
::read(whole
.as_ptr().add(K
::USIZE
) as *const _
);
302 unsafe impl<'a
, T
, N
, K
> Split
<T
, K
> for &'a GenericArray
<T
, N
>
305 K
: ArrayLength
<T
> + '
static,
307 Diff
<N
, K
>: ArrayLength
<T
>,
309 type First
= &'a GenericArray
<T
, K
>;
310 type Second
= &'a GenericArray
<T
, Diff
<N
, K
>>;
312 fn split(self) -> (Self::First
, Self::Second
) {
314 let ptr_to_first
: *const T
= self.as_ptr();
315 let head
= &*(ptr_to_first
as *const _
);
316 let tail
= &*(ptr_to_first
.add(K
::USIZE
) as *const _
);
322 unsafe impl<'a
, T
, N
, K
> Split
<T
, K
> for &'a
mut GenericArray
<T
, N
>
325 K
: ArrayLength
<T
> + '
static,
327 Diff
<N
, K
>: ArrayLength
<T
>,
329 type First
= &'a
mut GenericArray
<T
, K
>;
330 type Second
= &'a
mut GenericArray
<T
, Diff
<N
, K
>>;
332 fn split(self) -> (Self::First
, Self::Second
) {
334 let ptr_to_first
: *mut T
= self.as_mut_ptr();
335 let head
= &mut *(ptr_to_first
as *mut _
);
336 let tail
= &mut *(ptr_to_first
.add(K
::USIZE
) as *mut _
);
342 /// Defines `GenericSequence`s which can be joined together, forming a larger array.
343 pub unsafe trait Concat
<T
, M
>: GenericSequence
<T
>
347 /// Sequence to be concatenated with `self`
348 type Rest
: GenericSequence
<T
, Length
= M
>;
350 /// Resulting sequence formed by the concatenation.
351 type Output
: GenericSequence
<T
>;
353 /// Concatenate, or join, two sequences.
354 fn concat(self, rest
: Self::Rest
) -> Self::Output
;
357 unsafe impl<T
, N
, M
> Concat
<T
, M
> for GenericArray
<T
, N
>
359 N
: ArrayLength
<T
> + Add
<M
>,
361 Sum
<N
, M
>: ArrayLength
<T
>,
363 type Rest
= GenericArray
<T
, M
>;
364 type Output
= GenericArray
<T
, Sum
<N
, M
>>;
366 fn concat(self, rest
: Self::Rest
) -> Self::Output
{
367 let mut output
: MaybeUninit
<Self::Output
> = MaybeUninit
::uninit();
369 let out_ptr
= output
.as_mut_ptr() as *mut Self;
372 // write all of self to the pointer
373 ptr
::write(out_ptr
, self);
374 // increment past self, then write the rest
375 ptr
::write(out_ptr
.add(1) as *mut _
, rest
);