Coverage Report

Created: 2025-11-11 06:39

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