Coverage Report

Created: 2025-07-14 07:05

/rust/registry/src/index.crates.io-6f17d22bba15001f/generic-array-0.14.7/src/lib.rs
Line
Count
Source (jump to first uncovered line)
1
//! This crate implements a structure that can be used as a generic array type.
2
//! Core Rust array types `[T; N]` can't be used generically with
3
//! respect to `N`, so for example this:
4
//!
5
//! ```rust{compile_fail}
6
//! struct Foo<T, N> {
7
//!     data: [T; N]
8
//! }
9
//! ```
10
//!
11
//! won't work.
12
//!
13
//! **generic-array** exports a `GenericArray<T,N>` type, which lets
14
//! the above be implemented as:
15
//!
16
//! ```rust
17
//! use generic_array::{ArrayLength, GenericArray};
18
//!
19
//! struct Foo<T, N: ArrayLength<T>> {
20
//!     data: GenericArray<T,N>
21
//! }
22
//! ```
23
//!
24
//! The `ArrayLength<T>` trait is implemented by default for
25
//! [unsigned integer types](../typenum/uint/index.html) from
26
//! [typenum](../typenum/index.html):
27
//!
28
//! ```rust
29
//! # use generic_array::{ArrayLength, GenericArray};
30
//! use generic_array::typenum::U5;
31
//!
32
//! struct Foo<N: ArrayLength<i32>> {
33
//!     data: GenericArray<i32, N>
34
//! }
35
//!
36
//! # fn main() {
37
//! let foo = Foo::<U5>{data: GenericArray::default()};
38
//! # }
39
//! ```
40
//!
41
//! For example, `GenericArray<T, U5>` would work almost like `[T; 5]`:
42
//!
43
//! ```rust
44
//! # use generic_array::{ArrayLength, GenericArray};
45
//! use generic_array::typenum::U5;
46
//!
47
//! struct Foo<T, N: ArrayLength<T>> {
48
//!     data: GenericArray<T, N>
49
//! }
50
//!
51
//! # fn main() {
52
//! let foo = Foo::<i32, U5>{data: GenericArray::default()};
53
//! # }
54
//! ```
55
//!
56
//! For ease of use, an `arr!` macro is provided - example below:
57
//!
58
//! ```
59
//! # #[macro_use]
60
//! # extern crate generic_array;
61
//! # extern crate typenum;
62
//! # fn main() {
63
//! let array = arr![u32; 1, 2, 3];
64
//! assert_eq!(array[2], 3);
65
//! # }
66
//! ```
67
68
#![deny(missing_docs)]
69
#![deny(meta_variable_misuse)]
70
#![no_std]
71
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
72
73
#[cfg(feature = "serde")]
74
extern crate serde;
75
76
#[cfg(feature = "zeroize")]
77
extern crate zeroize;
78
79
#[cfg(test)]
80
extern crate bincode;
81
82
pub extern crate typenum;
83
84
mod hex;
85
mod impls;
86
87
#[cfg(feature = "serde")]
88
mod impl_serde;
89
90
#[cfg(feature = "zeroize")]
91
mod impl_zeroize;
92
93
use core::iter::FromIterator;
94
use core::marker::PhantomData;
95
use core::mem::{MaybeUninit, ManuallyDrop};
96
use core::ops::{Deref, DerefMut};
97
use core::{mem, ptr, slice};
98
use typenum::bit::{B0, B1};
99
use typenum::uint::{UInt, UTerm, Unsigned};
100
101
#[cfg_attr(test, macro_use)]
102
pub mod arr;
103
pub mod functional;
104
pub mod iter;
105
pub mod sequence;
106
107
use self::functional::*;
108
pub use self::iter::GenericArrayIter;
109
use self::sequence::*;
110
111
/// Trait making `GenericArray` work, marking types to be used as length of an array
112
pub unsafe trait ArrayLength<T>: Unsigned {
113
    /// Associated type representing the array type for the number
114
    type ArrayType;
115
}
116
117
unsafe impl<T> ArrayLength<T> for UTerm {
118
    #[doc(hidden)]
119
    type ArrayType = [T; 0];
120
}
121
122
/// Internal type used to generate a struct of appropriate size
123
#[allow(dead_code)]
124
#[repr(C)]
125
#[doc(hidden)]
126
pub struct GenericArrayImplEven<T, U> {
127
    parent1: U,
128
    parent2: U,
129
    _marker: PhantomData<T>,
130
}
131
132
impl<T: Clone, U: Clone> Clone for GenericArrayImplEven<T, U> {
133
0
    fn clone(&self) -> GenericArrayImplEven<T, U> {
134
0
        GenericArrayImplEven {
135
0
            parent1: self.parent1.clone(),
136
0
            parent2: self.parent2.clone(),
137
0
            _marker: PhantomData,
138
0
        }
139
0
    }
140
}
141
142
impl<T: Copy, U: Copy> Copy for GenericArrayImplEven<T, U> {}
143
144
/// Internal type used to generate a struct of appropriate size
145
#[allow(dead_code)]
146
#[repr(C)]
147
#[doc(hidden)]
148
pub struct GenericArrayImplOdd<T, U> {
149
    parent1: U,
150
    parent2: U,
151
    data: T,
152
}
153
154
impl<T: Clone, U: Clone> Clone for GenericArrayImplOdd<T, U> {
155
0
    fn clone(&self) -> GenericArrayImplOdd<T, U> {
156
0
        GenericArrayImplOdd {
157
0
            parent1: self.parent1.clone(),
158
0
            parent2: self.parent2.clone(),
159
0
            data: self.data.clone(),
160
0
        }
161
0
    }
162
}
163
164
impl<T: Copy, U: Copy> Copy for GenericArrayImplOdd<T, U> {}
165
166
unsafe impl<T, N: ArrayLength<T>> ArrayLength<T> for UInt<N, B0> {
167
    #[doc(hidden)]
168
    type ArrayType = GenericArrayImplEven<T, N::ArrayType>;
169
}
170
171
unsafe impl<T, N: ArrayLength<T>> ArrayLength<T> for UInt<N, B1> {
172
    #[doc(hidden)]
173
    type ArrayType = GenericArrayImplOdd<T, N::ArrayType>;
174
}
175
176
/// Struct representing a generic array - `GenericArray<T, N>` works like [T; N]
177
#[allow(dead_code)]
178
#[repr(transparent)]
179
pub struct GenericArray<T, U: ArrayLength<T>> {
180
    data: U::ArrayType,
181
}
182
183
unsafe impl<T: Send, N: ArrayLength<T>> Send for GenericArray<T, N> {}
184
unsafe impl<T: Sync, N: ArrayLength<T>> Sync for GenericArray<T, N> {}
185
186
impl<T, N> Deref for GenericArray<T, N>
187
where
188
    N: ArrayLength<T>,
189
{
190
    type Target = [T];
191
192
    #[inline(always)]
193
0
    fn deref(&self) -> &[T] {
194
0
        unsafe { slice::from_raw_parts(self as *const Self as *const T, N::USIZE) }
195
0
    }
Unexecuted instantiation: <generic_array::GenericArray<u8, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>> as core::ops::deref::Deref>::deref
Unexecuted instantiation: <generic_array::GenericArray<u8, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>> as core::ops::deref::Deref>::deref
Unexecuted instantiation: <generic_array::GenericArray<_, _> as core::ops::deref::Deref>::deref
196
}
197
198
impl<T, N> DerefMut for GenericArray<T, N>
199
where
200
    N: ArrayLength<T>,
201
{
202
    #[inline(always)]
203
0
    fn deref_mut(&mut self) -> &mut [T] {
204
0
        unsafe { slice::from_raw_parts_mut(self as *mut Self as *mut T, N::USIZE) }
205
0
    }
Unexecuted instantiation: <generic_array::GenericArray<u8, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>> as core::ops::deref::DerefMut>::deref_mut
Unexecuted instantiation: <generic_array::GenericArray<u8, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>> as core::ops::deref::DerefMut>::deref_mut
Unexecuted instantiation: <generic_array::GenericArray<u8, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>> as core::ops::deref::DerefMut>::deref_mut
Unexecuted instantiation: <generic_array::GenericArray<_, _> as core::ops::deref::DerefMut>::deref_mut
206
}
207
208
/// Creates an array one element at a time using a mutable iterator
209
/// you can write to with `ptr::write`.
210
///
211
/// Increment the position while iterating to mark off created elements,
212
/// which will be dropped if `into_inner` is not called.
213
#[doc(hidden)]
214
pub struct ArrayBuilder<T, N: ArrayLength<T>> {
215
    array: MaybeUninit<GenericArray<T, N>>,
216
    position: usize,
217
}
218
219
impl<T, N: ArrayLength<T>> ArrayBuilder<T, N> {
220
    #[doc(hidden)]
221
    #[inline]
222
0
    pub unsafe fn new() -> ArrayBuilder<T, N> {
223
0
        ArrayBuilder {
224
0
            array: MaybeUninit::uninit(),
225
0
            position: 0,
226
0
        }
227
0
    }
Unexecuted instantiation: <generic_array::ArrayBuilder<u8, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>>>::new
Unexecuted instantiation: <generic_array::ArrayBuilder<u8, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>>>::new
Unexecuted instantiation: <generic_array::ArrayBuilder<u8, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>>>::new
Unexecuted instantiation: <generic_array::ArrayBuilder<_, _>>::new
228
229
    /// Creates a mutable iterator for writing to the array using `ptr::write`.
230
    ///
231
    /// Increment the position value given as a mutable reference as you iterate
232
    /// to mark how many elements have been created.
233
    #[doc(hidden)]
234
    #[inline]
235
0
    pub unsafe fn iter_position(&mut self) -> (slice::IterMut<T>, &mut usize) {
236
0
        ((&mut *self.array.as_mut_ptr()).iter_mut(), &mut self.position)
237
0
    }
Unexecuted instantiation: <generic_array::ArrayBuilder<u8, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>>>::iter_position
Unexecuted instantiation: <generic_array::ArrayBuilder<u8, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>>>::iter_position
Unexecuted instantiation: <generic_array::ArrayBuilder<u8, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>>>::iter_position
Unexecuted instantiation: <generic_array::ArrayBuilder<_, _>>::iter_position
238
239
    /// When done writing (assuming all elements have been written to),
240
    /// get the inner array.
241
    #[doc(hidden)]
242
    #[inline]
243
0
    pub unsafe fn into_inner(self) -> GenericArray<T, N> {
244
0
        let array = ptr::read(&self.array);
245
0
246
0
        mem::forget(self);
247
0
248
0
        array.assume_init()
249
0
    }
Unexecuted instantiation: <generic_array::ArrayBuilder<u8, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>>>::into_inner
Unexecuted instantiation: <generic_array::ArrayBuilder<u8, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>>>::into_inner
Unexecuted instantiation: <generic_array::ArrayBuilder<u8, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>>>::into_inner
Unexecuted instantiation: <generic_array::ArrayBuilder<_, _>>::into_inner
250
}
251
252
impl<T, N: ArrayLength<T>> Drop for ArrayBuilder<T, N> {
253
0
    fn drop(&mut self) {
254
0
        if mem::needs_drop::<T>() {
255
            unsafe {
256
0
                for value in &mut (&mut *self.array.as_mut_ptr())[..self.position] {
257
0
                    ptr::drop_in_place(value);
258
0
                }
259
            }
260
0
        }
261
0
    }
Unexecuted instantiation: <generic_array::ArrayBuilder<u8, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>> as core::ops::drop::Drop>::drop
Unexecuted instantiation: <generic_array::ArrayBuilder<u8, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>> as core::ops::drop::Drop>::drop
Unexecuted instantiation: <generic_array::ArrayBuilder<u8, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>> as core::ops::drop::Drop>::drop
Unexecuted instantiation: <generic_array::ArrayBuilder<_, _> as core::ops::drop::Drop>::drop
262
}
263
264
/// Consumes an array.
265
///
266
/// Increment the position while iterating and any leftover elements
267
/// will be dropped if position does not go to N
268
#[doc(hidden)]
269
pub struct ArrayConsumer<T, N: ArrayLength<T>> {
270
    array: ManuallyDrop<GenericArray<T, N>>,
271
    position: usize,
272
}
273
274
impl<T, N: ArrayLength<T>> ArrayConsumer<T, N> {
275
    #[doc(hidden)]
276
    #[inline]
277
0
    pub unsafe fn new(array: GenericArray<T, N>) -> ArrayConsumer<T, N> {
278
0
        ArrayConsumer {
279
0
            array: ManuallyDrop::new(array),
280
0
            position: 0,
281
0
        }
282
0
    }
283
284
    /// Creates an iterator and mutable reference to the internal position
285
    /// to keep track of consumed elements.
286
    ///
287
    /// Increment the position as you iterate to mark off consumed elements
288
    #[doc(hidden)]
289
    #[inline]
290
0
    pub unsafe fn iter_position(&mut self) -> (slice::Iter<T>, &mut usize) {
291
0
        (self.array.iter(), &mut self.position)
292
0
    }
293
}
294
295
impl<T, N: ArrayLength<T>> Drop for ArrayConsumer<T, N> {
296
0
    fn drop(&mut self) {
297
0
        if mem::needs_drop::<T>() {
298
0
            for value in &mut self.array[self.position..N::USIZE] {
299
0
                unsafe {
300
0
                    ptr::drop_in_place(value);
301
0
                }
302
            }
303
0
        }
304
0
    }
305
}
306
307
impl<'a, T: 'a, N> IntoIterator for &'a GenericArray<T, N>
308
where
309
    N: ArrayLength<T>,
310
{
311
    type IntoIter = slice::Iter<'a, T>;
312
    type Item = &'a T;
313
314
0
    fn into_iter(self: &'a GenericArray<T, N>) -> Self::IntoIter {
315
0
        self.as_slice().iter()
316
0
    }
317
}
318
319
impl<'a, T: 'a, N> IntoIterator for &'a mut GenericArray<T, N>
320
where
321
    N: ArrayLength<T>,
322
{
323
    type IntoIter = slice::IterMut<'a, T>;
324
    type Item = &'a mut T;
325
326
0
    fn into_iter(self: &'a mut GenericArray<T, N>) -> Self::IntoIter {
327
0
        self.as_mut_slice().iter_mut()
328
0
    }
329
}
330
331
impl<T, N> FromIterator<T> for GenericArray<T, N>
332
where
333
    N: ArrayLength<T>,
334
{
335
0
    fn from_iter<I>(iter: I) -> GenericArray<T, N>
336
0
    where
337
0
        I: IntoIterator<Item = T>,
338
0
    {
339
0
        unsafe {
340
0
            let mut destination = ArrayBuilder::new();
341
0
342
0
            {
343
0
                let (destination_iter, position) = destination.iter_position();
344
0
345
0
                iter.into_iter()
346
0
                    .zip(destination_iter)
347
0
                    .for_each(|(src, dst)| {
348
0
                        ptr::write(dst, src);
349
0
350
0
                        *position += 1;
351
0
                    });
352
0
            }
353
0
354
0
            if destination.position < N::USIZE {
355
0
                from_iter_length_fail(destination.position, N::USIZE);
356
0
            }
357
0
358
0
            destination.into_inner()
359
0
        }
360
0
    }
361
}
362
363
#[inline(never)]
364
#[cold]
365
0
fn from_iter_length_fail(length: usize, expected: usize) -> ! {
366
0
    panic!(
367
0
        "GenericArray::from_iter received {} elements but expected {}",
368
0
        length, expected
369
0
    );
370
}
371
372
unsafe impl<T, N> GenericSequence<T> for GenericArray<T, N>
373
where
374
    N: ArrayLength<T>,
375
    Self: IntoIterator<Item = T>,
376
{
377
    type Length = N;
378
    type Sequence = Self;
379
380
0
    fn generate<F>(mut f: F) -> GenericArray<T, N>
381
0
    where
382
0
        F: FnMut(usize) -> T,
383
0
    {
384
0
        unsafe {
385
0
            let mut destination = ArrayBuilder::new();
386
0
387
0
            {
388
0
                let (destination_iter, position) = destination.iter_position();
389
0
390
0
                destination_iter.enumerate().for_each(|(i, dst)| {
391
0
                    ptr::write(dst, f(i));
392
0
393
0
                    *position += 1;
394
0
                });
Unexecuted instantiation: <generic_array::GenericArray<u8, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>> as generic_array::sequence::GenericSequence<u8>>::generate::<<generic_array::GenericArray<u8, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>> as core::default::Default>::default::{closure#0}>::{closure#0}
Unexecuted instantiation: <generic_array::GenericArray<u8, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>> as generic_array::sequence::GenericSequence<u8>>::generate::<<generic_array::GenericArray<u8, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>> as core::default::Default>::default::{closure#0}>::{closure#0}
Unexecuted instantiation: <generic_array::GenericArray<u8, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>> as generic_array::sequence::GenericSequence<u8>>::generate::<<generic_array::GenericArray<u8, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>> as core::default::Default>::default::{closure#0}>::{closure#0}
Unexecuted instantiation: <generic_array::GenericArray<_, _> as generic_array::sequence::GenericSequence<_>>::generate::<_>::{closure#0}
395
0
            }
396
0
397
0
            destination.into_inner()
398
0
        }
399
0
    }
Unexecuted instantiation: <generic_array::GenericArray<u8, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>> as generic_array::sequence::GenericSequence<u8>>::generate::<<generic_array::GenericArray<u8, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>> as core::default::Default>::default::{closure#0}>
Unexecuted instantiation: <generic_array::GenericArray<u8, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>> as generic_array::sequence::GenericSequence<u8>>::generate::<<generic_array::GenericArray<u8, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>> as core::default::Default>::default::{closure#0}>
Unexecuted instantiation: <generic_array::GenericArray<u8, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>> as generic_array::sequence::GenericSequence<u8>>::generate::<<generic_array::GenericArray<u8, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>> as core::default::Default>::default::{closure#0}>
Unexecuted instantiation: <generic_array::GenericArray<_, _> as generic_array::sequence::GenericSequence<_>>::generate::<_>
400
401
    #[doc(hidden)]
402
0
    fn inverted_zip<B, U, F>(
403
0
        self,
404
0
        lhs: GenericArray<B, Self::Length>,
405
0
        mut f: F,
406
0
    ) -> MappedSequence<GenericArray<B, Self::Length>, B, U>
407
0
    where
408
0
        GenericArray<B, Self::Length>:
409
0
            GenericSequence<B, Length = Self::Length> + MappedGenericSequence<B, U>,
410
0
        Self: MappedGenericSequence<T, U>,
411
0
        Self::Length: ArrayLength<B> + ArrayLength<U>,
412
0
        F: FnMut(B, Self::Item) -> U,
413
0
    {
414
0
        unsafe {
415
0
            let mut left = ArrayConsumer::new(lhs);
416
0
            let mut right = ArrayConsumer::new(self);
417
0
418
0
            let (left_array_iter, left_position) = left.iter_position();
419
0
            let (right_array_iter, right_position) = right.iter_position();
420
0
421
0
            FromIterator::from_iter(left_array_iter.zip(right_array_iter).map(|(l, r)| {
422
0
                let left_value = ptr::read(l);
423
0
                let right_value = ptr::read(r);
424
0
425
0
                *left_position += 1;
426
0
                *right_position += 1;
427
0
428
0
                f(left_value, right_value)
429
0
            }))
430
0
        }
431
0
    }
432
433
    #[doc(hidden)]
434
0
    fn inverted_zip2<B, Lhs, U, F>(self, lhs: Lhs, mut f: F) -> MappedSequence<Lhs, B, U>
435
0
    where
436
0
        Lhs: GenericSequence<B, Length = Self::Length> + MappedGenericSequence<B, U>,
437
0
        Self: MappedGenericSequence<T, U>,
438
0
        Self::Length: ArrayLength<B> + ArrayLength<U>,
439
0
        F: FnMut(Lhs::Item, Self::Item) -> U,
440
0
    {
441
0
        unsafe {
442
0
            let mut right = ArrayConsumer::new(self);
443
0
444
0
            let (right_array_iter, right_position) = right.iter_position();
445
0
446
0
            FromIterator::from_iter(
447
0
                lhs.into_iter()
448
0
                    .zip(right_array_iter)
449
0
                    .map(|(left_value, r)| {
450
0
                        let right_value = ptr::read(r);
451
0
452
0
                        *right_position += 1;
453
0
454
0
                        f(left_value, right_value)
455
0
                    }),
456
0
            )
457
0
        }
458
0
    }
459
}
460
461
unsafe impl<T, U, N> MappedGenericSequence<T, U> for GenericArray<T, N>
462
where
463
    N: ArrayLength<T> + ArrayLength<U>,
464
    GenericArray<U, N>: GenericSequence<U, Length = N>,
465
{
466
    type Mapped = GenericArray<U, N>;
467
}
468
469
unsafe impl<T, N> FunctionalSequence<T> for GenericArray<T, N>
470
where
471
    N: ArrayLength<T>,
472
    Self: GenericSequence<T, Item = T, Length = N>,
473
{
474
0
    fn map<U, F>(self, mut f: F) -> MappedSequence<Self, T, U>
475
0
    where
476
0
        Self::Length: ArrayLength<U>,
477
0
        Self: MappedGenericSequence<T, U>,
478
0
        F: FnMut(T) -> U,
479
0
    {
480
0
        unsafe {
481
0
            let mut source = ArrayConsumer::new(self);
482
0
483
0
            let (array_iter, position) = source.iter_position();
484
0
485
0
            FromIterator::from_iter(array_iter.map(|src| {
486
0
                let value = ptr::read(src);
487
0
488
0
                *position += 1;
489
0
490
0
                f(value)
491
0
            }))
492
0
        }
493
0
    }
494
495
    #[inline]
496
0
    fn zip<B, Rhs, U, F>(self, rhs: Rhs, f: F) -> MappedSequence<Self, T, U>
497
0
    where
498
0
        Self: MappedGenericSequence<T, U>,
499
0
        Rhs: MappedGenericSequence<B, U, Mapped = MappedSequence<Self, T, U>>,
500
0
        Self::Length: ArrayLength<B> + ArrayLength<U>,
501
0
        Rhs: GenericSequence<B, Length = Self::Length>,
502
0
        F: FnMut(T, Rhs::Item) -> U,
503
0
    {
504
0
        rhs.inverted_zip(self, f)
505
0
    }
506
507
0
    fn fold<U, F>(self, init: U, mut f: F) -> U
508
0
    where
509
0
        F: FnMut(U, T) -> U,
510
0
    {
511
0
        unsafe {
512
0
            let mut source = ArrayConsumer::new(self);
513
0
514
0
            let (array_iter, position) = source.iter_position();
515
0
516
0
            array_iter.fold(init, |acc, src| {
517
0
                let value = ptr::read(src);
518
0
519
0
                *position += 1;
520
0
521
0
                f(acc, value)
522
0
            })
523
0
        }
524
0
    }
525
}
526
527
impl<T, N> GenericArray<T, N>
528
where
529
    N: ArrayLength<T>,
530
{
531
    /// Extracts a slice containing the entire array.
532
    #[inline]
533
0
    pub fn as_slice(&self) -> &[T] {
534
0
        self.deref()
535
0
    }
Unexecuted instantiation: <generic_array::GenericArray<u8, typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>, typenum::bit::B1>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>, typenum::bit::B0>>>::as_slice
Unexecuted instantiation: <generic_array::GenericArray<_, _>>::as_slice
536
537
    /// Extracts a mutable slice containing the entire array.
538
    #[inline]
539
0
    pub fn as_mut_slice(&mut self) -> &mut [T] {
540
0
        self.deref_mut()
541
0
    }
542
543
    /// Converts slice to a generic array reference with inferred length;
544
    ///
545
    /// # Panics
546
    ///
547
    /// Panics if the slice is not equal to the length of the array.
548
    #[inline]
549
0
    pub fn from_slice(slice: &[T]) -> &GenericArray<T, N> {
550
0
        slice.into()
551
0
    }
552
553
    /// Converts mutable slice to a mutable generic array reference
554
    ///
555
    /// # Panics
556
    ///
557
    /// Panics if the slice is not equal to the length of the array.
558
    #[inline]
559
0
    pub fn from_mut_slice(slice: &mut [T]) -> &mut GenericArray<T, N> {
560
0
        slice.into()
561
0
    }
562
}
563
564
impl<'a, T, N: ArrayLength<T>> From<&'a [T]> for &'a GenericArray<T, N> {
565
    /// Converts slice to a generic array reference with inferred length;
566
    ///
567
    /// # Panics
568
    ///
569
    /// Panics if the slice is not equal to the length of the array.
570
    #[inline]
571
0
    fn from(slice: &[T]) -> &GenericArray<T, N> {
572
0
        assert_eq!(slice.len(), N::USIZE);
573
574
0
        unsafe { &*(slice.as_ptr() as *const GenericArray<T, N>) }
575
0
    }
576
}
577
578
impl<'a, T, N: ArrayLength<T>> From<&'a mut [T]> for &'a mut GenericArray<T, N> {
579
    /// Converts mutable slice to a mutable generic array reference
580
    ///
581
    /// # Panics
582
    ///
583
    /// Panics if the slice is not equal to the length of the array.
584
    #[inline]
585
0
    fn from(slice: &mut [T]) -> &mut GenericArray<T, N> {
586
0
        assert_eq!(slice.len(), N::USIZE);
587
588
0
        unsafe { &mut *(slice.as_mut_ptr() as *mut GenericArray<T, N>) }
589
0
    }
590
}
591
592
impl<T: Clone, N> GenericArray<T, N>
593
where
594
    N: ArrayLength<T>,
595
{
596
    /// Construct a `GenericArray` from a slice by cloning its content
597
    ///
598
    /// # Panics
599
    ///
600
    /// Panics if the slice is not equal to the length of the array.
601
    #[inline]
602
0
    pub fn clone_from_slice(list: &[T]) -> GenericArray<T, N> {
603
0
        Self::from_exact_iter(list.iter().cloned())
604
0
            .expect("Slice must be the same length as the array")
605
0
    }
606
}
607
608
impl<T, N> GenericArray<T, N>
609
where
610
    N: ArrayLength<T>,
611
{
612
    /// Creates a new `GenericArray` instance from an iterator with a specific size.
613
    ///
614
    /// Returns `None` if the size is not equal to the number of elements in the `GenericArray`.
615
0
    pub fn from_exact_iter<I>(iter: I) -> Option<Self>
616
0
    where
617
0
        I: IntoIterator<Item = T>,
618
0
    {
619
0
        let mut iter = iter.into_iter();
620
0
621
0
        unsafe {
622
0
            let mut destination = ArrayBuilder::new();
623
0
624
0
            {
625
0
                let (destination_iter, position) = destination.iter_position();
626
0
627
0
                destination_iter.zip(&mut iter).for_each(|(dst, src)| {
628
0
                    ptr::write(dst, src);
629
0
630
0
                    *position += 1;
631
0
                });
632
0
633
0
                // The iterator produced fewer than `N` elements.
634
0
                if *position != N::USIZE {
635
0
                    return None;
636
0
                }
637
0
638
0
                // The iterator produced more than `N` elements.
639
0
                if iter.next().is_some() {
640
0
                    return None;
641
0
                }
642
0
            }
643
0
644
0
            Some(destination.into_inner())
645
        }
646
0
    }
647
}
648
649
/// A reimplementation of the `transmute` function, avoiding problems
650
/// when the compiler can't prove equal sizes.
651
#[inline]
652
#[doc(hidden)]
653
0
pub unsafe fn transmute<A, B>(a: A) -> B {
654
0
    let a = ManuallyDrop::new(a);
655
0
    ::core::ptr::read(&*a as *const A as *const B)
656
0
}
657
658
#[cfg(test)]
659
mod test {
660
    // Compile with:
661
    // cargo rustc --lib --profile test --release --
662
    //      -C target-cpu=native -C opt-level=3 --emit asm
663
    // and view the assembly to make sure test_assembly generates
664
    // SIMD instructions instead of a naive loop.
665
666
    #[inline(never)]
667
    pub fn black_box<T>(val: T) -> T {
668
        use core::{mem, ptr};
669
670
        let ret = unsafe { ptr::read_volatile(&val) };
671
        mem::forget(val);
672
        ret
673
    }
674
675
    #[test]
676
    fn test_assembly() {
677
        use crate::functional::*;
678
679
        let a = black_box(arr![i32; 1, 3, 5, 7]);
680
        let b = black_box(arr![i32; 2, 4, 6, 8]);
681
682
        let c = (&a).zip(b, |l, r| l + r);
683
684
        let d = a.fold(0, |a, x| a + x);
685
686
        assert_eq!(c, arr![i32; 3, 7, 11, 15]);
687
688
        assert_eq!(d, 16);
689
    }
690
}