//! Useful traits for manipulating sequences of data stored in `GenericArray`s
usesuper::*; use core::ops::{Add, Sub}; use core::mem::MaybeUninit; use core::ptr; use typenum::operator_aliases::*;
/// Defines some sequence with an associated length and iteration capabilities. /// /// This is useful for passing N-length generic arrays as generics. pubunsafetrait GenericSequence<T>: Sized + IntoIterator { /// `GenericArray` associated length type Length: ArrayLength<T>;
/// Concrete sequence type used in conjuction with reference implementations of `GenericSequence` type Sequence: GenericSequence<T, Length = Self::Length> + FromIterator<T>;
/// Initializes a new sequence instance using the given function. /// /// If the generator function panics while initializing the sequence, /// any already initialized elements will be dropped. fn generate<F>(f: F) -> Self::Sequence where
F: FnMut(usize) -> T;
/// Accessor for `GenericSequence` item type, which is really `IntoIterator::Item` /// /// For deeply nested generic mapped sequence types, like shown in `tests/generics.rs`, /// this can be useful for keeping things organized. pubtype SequenceItem<T> = <T as IntoIterator>::Item;
unsafeimpl<'a, T: 'a, S: GenericSequence<T>> GenericSequence<T> for &'a S where
&'a S: IntoIterator,
{ type Length = S::Length; type Sequence = S::Sequence;
unsafeimpl<'a, T: 'a, S: GenericSequence<T>> GenericSequence<T> for &'a mut S where
&'a mut S: IntoIterator,
{ type Length = S::Length; type Sequence = S::Sequence;
/// Defines any `GenericSequence` which can be lengthened or extended by appending /// or prepending an element to it. /// /// Any lengthened sequence can be shortened back to the original using `pop_front` or `pop_back` pubunsafetrait Lengthen<T>: Sized + GenericSequence<T> { /// `GenericSequence` that has one more element than `Self` type Longer: Shorten<T, Shorter = Self>;
/// Returns a new array with the given element appended to the end of it. /// /// Example: /// /// ```rust /// # use generic_array::{arr, sequence::Lengthen}; /// # fn main() { /// let a = arr![i32; 1, 2, 3]; /// /// let b = a.append(4); /// /// assert_eq!(b, arr![i32; 1, 2, 3, 4]); /// # } /// ``` fn append(self, last: T) -> Self::Longer;
/// Returns a new array with the given element prepended to the front of it. /// /// Example: /// /// ```rust /// # use generic_array::{arr, sequence::Lengthen}; /// # fn main() { /// let a = arr![i32; 1, 2, 3]; /// /// let b = a.prepend(4); /// /// assert_eq!(b, arr![i32; 4, 1, 2, 3]); /// # } /// ``` fn prepend(self, first: T) -> Self::Longer;
}
/// Defines a `GenericSequence` which can be shortened by removing the first or last element from it. /// /// Additionally, any shortened sequence can be lengthened by /// appending or prepending an element to it. pubunsafetrait Shorten<T>: Sized + GenericSequence<T> { /// `GenericSequence` that has one less element than `Self` type Shorter: Lengthen<T, Longer = Self>;
/// Returns a new array without the last element, and the last element. /// /// Example: /// /// ```rust /// # use generic_array::{arr, sequence::Shorten}; /// # fn main() { /// let a = arr![i32; 1, 2, 3, 4]; /// /// let (init, last) = a.pop_back(); /// /// assert_eq!(init, arr![i32; 1, 2, 3]); /// assert_eq!(last, 4); /// # } /// ``` fn pop_back(self) -> (Self::Shorter, T);
/// Returns a new array without the first element, and the first element. /// Example: /// /// ```rust /// # use generic_array::{arr, sequence::Shorten}; /// # fn main() { /// let a = arr![i32; 1, 2, 3, 4]; /// /// let (head, tail) = a.pop_front(); /// /// assert_eq!(head, 1); /// assert_eq!(tail, arr![i32; 2, 3, 4]); /// # } /// ``` fn pop_front(self) -> (T, Self::Shorter);
}
unsafeimpl<T, N: ArrayLength<T>> Lengthen<T> for GenericArray<T, N> where
N: Add<B1>,
Add1<N>: ArrayLength<T>,
Add1<N>: Sub<B1, Output = N>,
Sub1<Add1<N>>: ArrayLength<T>,
{ type Longer = GenericArray<T, Add1<N>>;
// Note this is *mut T, so add(1) increments by a single T let out_ptr = longer.as_mut_ptr() as *mut T;
unsafe { // write the first at the start
ptr::write(out_ptr, first); // increment past the first, then write self
ptr::write(out_ptr.add(1) as *mutSelf, self);
longer.assume_init()
}
}
}
unsafeimpl<T, N: ArrayLength<T>> Shorten<T> for GenericArray<T, N> where
N: Sub<B1>,
Sub1<N>: ArrayLength<T>,
Sub1<N>: Add<B1, Output = N>,
Add1<Sub1<N>>: ArrayLength<T>,
{ type Shorter = GenericArray<T, Sub1<N>>;
fn pop_back(self) -> (Self::Shorter, T) { let whole = ManuallyDrop::new(self);
unsafe { let init = ptr::read(whole.as_ptr() as _); let last = ptr::read(whole.as_ptr().add(Sub1::<N>::USIZE) as _);
(init, last)
}
}
fn pop_front(self) -> (T, Self::Shorter) { // ensure this doesn't get dropped let whole = ManuallyDrop::new(self);
unsafe { let head = ptr::read(whole.as_ptr() as _); let tail = ptr::read(whole.as_ptr().offset(1) as _);
(head, tail)
}
}
}
/// Defines a `GenericSequence` that can be split into two parts at a given pivot index. pubunsafetrait Split<T, K>: GenericSequence<T> where
K: ArrayLength<T>,
{ /// First part of the resulting split array type First: GenericSequence<T>; /// Second part of the resulting split array type Second: GenericSequence<T>;
/// Splits an array at the given index, returning the separate parts of the array. fn split(self) -> (Self::First, Self::Second);
}
unsafeimpl<T, N, K> Split<T, K> for GenericArray<T, N> where
N: ArrayLength<T>,
K: ArrayLength<T>,
N: Sub<K>,
Diff<N, K>: ArrayLength<T>,
{ type First = GenericArray<T, K>; type Second = GenericArray<T, Diff<N, K>>;
fn split(self) -> (Self::First, Self::Second) { unsafe { // ensure this doesn't get dropped let whole = ManuallyDrop::new(self);
let head = ptr::read(whole.as_ptr() as *const _); let tail = ptr::read(whole.as_ptr().add(K::USIZE) as *const _);
(head, tail)
}
}
}
unsafeimpl<'a, T, N, K> Split<T, K> for &'a GenericArray<T, N> where
N: ArrayLength<T>,
K: ArrayLength<T> + 'static,
N: Sub<K>,
Diff<N, K>: ArrayLength<T>,
{ type First = &'a GenericArray<T, K>; type Second = &'a GenericArray<T, Diff<N, K>>;
fn split(self) -> (Self::First, Self::Second) { unsafe { let ptr_to_first: *const T = self.as_ptr(); let head = &*(ptr_to_first as *const _); let tail = &*(ptr_to_first.add(K::USIZE) as *const _);
(head, tail)
}
}
}
unsafeimpl<'a, T, N, K> Split<T, K> for &'a mut GenericArray<T, N> where
N: ArrayLength<T>,
K: ArrayLength<T> + 'static,
N: Sub<K>,
Diff<N, K>: ArrayLength<T>,
{ type First = &'a mut GenericArray<T, K>; type Second = &'a mut GenericArray<T, Diff<N, K>>;
fn split(self) -> (Self::First, Self::Second) { unsafe { let ptr_to_first: *mut T = self.as_mut_ptr(); let head = &mut *(ptr_to_first as *mut _); let tail = &mut *(ptr_to_first.add(K::USIZE) as *mut _);
(head, tail)
}
}
}
/// Defines `GenericSequence`s which can be joined together, forming a larger array. pubunsafetrait Concat<T, M>: GenericSequence<T> where
M: ArrayLength<T>,
{ /// Sequence to be concatenated with `self` type Rest: GenericSequence<T, Length = M>;
/// Resulting sequence formed by the concatenation. type Output: GenericSequence<T>;
/// Concatenate, or join, two sequences. fn concat(self, rest: Self::Rest) -> Self::Output;
}
unsafeimpl<T, N, M> Concat<T, M> for GenericArray<T, N> where
N: ArrayLength<T> + Add<M>,
M: ArrayLength<T>,
Sum<N, M>: ArrayLength<T>,
{ type Rest = GenericArray<T, M>; type Output = GenericArray<T, Sum<N, M>>;
unsafe { // write all of self to the pointer
ptr::write(out_ptr, self); // increment past self, then write the rest
ptr::write(out_ptr.add(1) as *mut _, rest);
output.assume_init()
}
}
}
Messung V0.5 in Prozent
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.12Angebot
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-06-18)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.