1#![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")]
78extern crate serde;
79
80#[cfg(feature = "zeroize")]
81extern crate zeroize;
82
83#[cfg(test)]
84extern crate bincode;
85
86pub extern crate typenum;
87
88mod hex;
89mod impls;
90
91#[cfg(feature = "serde")]
92mod impl_serde;
93
94#[cfg(feature = "zeroize")]
95mod impl_zeroize;
96
97use core::iter::FromIterator;
98use core::marker::PhantomData;
99use core::mem::{MaybeUninit, ManuallyDrop};
100use core::ops::{Deref, DerefMut};
101use core::{mem, ptr, slice};
102use typenum::bit::{B0, B1};
103use typenum::uint::{UInt, UTerm, Unsigned};
104
105#[cfg_attr(test, macro_use)]
106pub mod arr;
107pub mod functional;
108pub mod iter;
109pub mod sequence;
110
111use self::functional::*;
112pub use self::iter::GenericArrayIter;
113use self::sequence::*;
114
115pub unsafe trait ArrayLength<T>: Unsigned {
117 type ArrayType;
119}
120
121unsafe impl<T> ArrayLength<T> for UTerm {
122 #[doc(hidden)]
123 type ArrayType = [T; 0];
124}
125
126#[allow(dead_code)]
128#[repr(C)]
129#[doc(hidden)]
130pub struct GenericArrayImplEven<T, U> {
131 parent1: U,
132 parent2: U,
133 _marker: PhantomData<T>,
134}
135
136impl<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
146impl<T: Copy, U: Copy> Copy for GenericArrayImplEven<T, U> {}
147
148#[allow(dead_code)]
150#[repr(C)]
151#[doc(hidden)]
152pub struct GenericArrayImplOdd<T, U> {
153 parent1: U,
154 parent2: U,
155 data: T,
156}
157
158impl<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
168impl<T: Copy, U: Copy> Copy for GenericArrayImplOdd<T, U> {}
169
170unsafe impl<T, N: ArrayLength<T>> ArrayLength<T> for UInt<N, B0> {
171 #[doc(hidden)]
172 type ArrayType = GenericArrayImplEven<T, N::ArrayType>;
173}
174
175unsafe impl<T, N: ArrayLength<T>> ArrayLength<T> for UInt<N, B1> {
176 #[doc(hidden)]
177 type ArrayType = GenericArrayImplOdd<T, N::ArrayType>;
178}
179
180#[allow(dead_code)]
182#[repr(transparent)]
183pub struct GenericArray<T, U: ArrayLength<T>> {
184 data: U::ArrayType,
185}
186
187unsafe impl<T: Send, N: ArrayLength<T>> Send for GenericArray<T, N> {}
188unsafe impl<T: Sync, N: ArrayLength<T>> Sync for GenericArray<T, N> {}
189
190impl<T, N> Deref for GenericArray<T, N>
191where
192 N: ArrayLength<T>,
193{
194 type Target = [T];
195
196 #[inline(always)]
197 fn deref(&self) -> &[T] {
198 unsafe { slice::from_raw_parts(self as *const Self as *const T, N::USIZE) }
199 }
200}
201
202impl<T, N> DerefMut for GenericArray<T, N>
203where
204 N: ArrayLength<T>,
205{
206 #[inline(always)]
207 fn deref_mut(&mut self) -> &mut [T] {
208 unsafe { slice::from_raw_parts_mut(self as *mut Self as *mut T, N::USIZE) }
209 }
210}
211
212#[doc(hidden)]
218pub struct ArrayBuilder<T, N: ArrayLength<T>> {
219 array: MaybeUninit<GenericArray<T, N>>,
220 position: usize,
221}
222
223impl<T, N: ArrayLength<T>> ArrayBuilder<T, N> {
224 #[doc(hidden)]
225 #[inline]
226 pub unsafe fn new() -> ArrayBuilder<T, N> {
227 ArrayBuilder {
228 array: MaybeUninit::uninit(),
229 position: 0,
230 }
231 }
232
233 #[doc(hidden)]
238 #[inline]
239 pub unsafe fn iter_position(&mut self) -> (slice::IterMut<T>, &mut usize) {
240 ((&mut *self.array.as_mut_ptr()).iter_mut(), &mut self.position)
241 }
242
243 #[doc(hidden)]
246 #[inline]
247 pub unsafe fn into_inner(self) -> GenericArray<T, N> {
248 let array = ptr::read(&self.array);
249
250 mem::forget(self);
251
252 array.assume_init()
253 }
254}
255
256impl<T, N: ArrayLength<T>> Drop for ArrayBuilder<T, N> {
257 fn drop(&mut self) {
258 if mem::needs_drop::<T>() {
259 unsafe {
260 for value in &mut (&mut *self.array.as_mut_ptr())[..self.position] {
261 ptr::drop_in_place(value);
262 }
263 }
264 }
265 }
266}
267
268#[doc(hidden)]
273pub struct ArrayConsumer<T, N: ArrayLength<T>> {
274 array: ManuallyDrop<GenericArray<T, N>>,
275 position: usize,
276}
277
278impl<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 #[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
299impl<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
311impl<'a, T: 'a, N> IntoIterator for &'a GenericArray<T, N>
312where
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
323impl<'a, T: 'a, N> IntoIterator for &'a mut GenericArray<T, N>
324where
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
335impl<T, N> FromIterator<T> for GenericArray<T, N>
336where
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]
369fn from_iter_length_fail(length: usize, expected: usize) -> ! {
370 panic!(
371 "GenericArray::from_iter received {} elements but expected {}",
372 length, expected
373 );
374}
375
376unsafe impl<T, N> GenericSequence<T> for GenericArray<T, N>
377where
378 N: ArrayLength<T>,
379 Self: IntoIterator<Item = T>,
380{
381 type Length = N;
382 type Sequence = Self;
383
384 fn generate<F>(mut f: F) -> GenericArray<T, N>
385 where
386 F: FnMut(usize) -> T,
387 {
388 unsafe {
389 let mut destination = ArrayBuilder::new();
390
391 {
392 let (destination_iter, position) = destination.iter_position();
393
394 destination_iter.enumerate().for_each(|(i, dst)| {
395 ptr::write(dst, f(i));
396
397 *position += 1;
398 });
399 }
400
401 destination.into_inner()
402 }
403 }
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
465unsafe impl<T, U, N> MappedGenericSequence<T, U> for GenericArray<T, N>
466where
467 N: ArrayLength<T> + ArrayLength<U>,
468 GenericArray<U, N>: GenericSequence<U, Length = N>,
469{
470 type Mapped = GenericArray<U, N>;
471}
472
473unsafe impl<T, N> FunctionalSequence<T> for GenericArray<T, N>
474where
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
531impl<T, N> GenericArray<T, N>
532where
533 N: ArrayLength<T>,
534{
535 #[inline]
537 pub fn as_slice(&self) -> &[T] {
538 self.deref()
539 }
540
541 #[inline]
543 pub fn as_mut_slice(&mut self) -> &mut [T] {
544 self.deref_mut()
545 }
546
547 #[inline]
553 pub fn from_slice(slice: &[T]) -> &GenericArray<T, N> {
554 slice.into()
555 }
556
557 #[inline]
563 pub fn from_mut_slice(slice: &mut [T]) -> &mut GenericArray<T, N> {
564 slice.into()
565 }
566}
567
568impl<'a, T, N: ArrayLength<T>> From<&'a [T]> for &'a GenericArray<T, N> {
569 #[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
582impl<'a, T, N: ArrayLength<T>> From<&'a mut [T]> for &'a mut GenericArray<T, N> {
583 #[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
596impl<T: Clone, N> GenericArray<T, N>
597where
598 N: ArrayLength<T>,
599{
600 #[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
612impl<T, N> GenericArray<T, N>
613where
614 N: ArrayLength<T>,
615{
616 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 if *position != N::USIZE {
639 return None;
640 }
641
642 if iter.next().is_some() {
644 return None;
645 }
646 }
647
648 Some(destination.into_inner())
649 }
650 }
651}
652
653#[inline]
656#[doc(hidden)]
657pub 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)]
663mod test {
664 #[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}