1#![no_std]
2#![cfg_attr(docsrs, feature(doc_cfg))]
3#![doc = include_str!("../README.md")]
4#![doc(
5 html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg",
6 html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg"
7)]
8
9#[cfg(feature = "alloc")]
99extern crate alloc;
100
101pub mod sizes;
102
103mod flatten;
104mod from_fn;
105mod iter;
106mod traits;
107
108#[cfg(feature = "serde")]
109mod serde;
110
111pub use crate::{
112 flatten::{Flatten, Unflatten},
113 iter::TryFromIteratorError,
114 traits::*,
115};
116pub use typenum;
117
118use core::{
119 array::TryFromSliceError,
120 borrow::{Borrow, BorrowMut},
121 cmp::Ordering,
122 fmt::{self, Debug},
123 hash::{Hash, Hasher},
124 mem::{self, ManuallyDrop, MaybeUninit},
125 ops::{Add, Deref, DerefMut, Index, IndexMut, Sub},
126 ptr,
127 slice::{self, Iter, IterMut},
128};
129use typenum::{Diff, Sum, U1};
130
131#[cfg(feature = "arbitrary")]
132use arbitrary::Arbitrary;
133
134#[cfg(feature = "bytemuck")]
135use bytemuck::{Pod, Zeroable};
136
137#[cfg(feature = "zeroize")]
138use zeroize::{Zeroize, ZeroizeOnDrop};
139
140#[cfg(feature = "zerocopy")]
141use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout, Unaligned};
142
143pub type ArrayN<T, const N: usize> = Array<T, <[T; N] as AssocArraySize>::Size>;
145
146#[cfg_attr(
161 feature = "zerocopy",
162 derive(IntoBytes, FromBytes, Immutable, Unaligned, KnownLayout)
163)]
164#[repr(transparent)]
165pub struct Array<T, U: ArraySize>(pub U::ArrayType<T>);
166
167type SplitResult<T, U, N> = (Array<T, N>, Array<T, Diff<U, N>>);
168type SplitRefResult<'a, T, U, N> = (&'a Array<T, N>, &'a Array<T, Diff<U, N>>);
169type SplitRefMutResult<'a, T, U, N> = (&'a mut Array<T, N>, &'a mut Array<T, Diff<U, N>>);
170
171impl<T, U> Array<T, U>
172where
173 U: ArraySize,
174{
175 #[inline]
177 pub const fn as_slice(&self) -> &[T] {
178 unsafe { slice::from_raw_parts(self.as_ptr(), U::USIZE) }
181 }
182
183 #[inline]
185 pub const fn as_mut_slice(&mut self) -> &mut [T] {
186 unsafe { slice::from_raw_parts_mut(self.as_mut_ptr(), U::USIZE) }
189 }
190
191 pub const fn as_ptr(&self) -> *const T {
193 ptr::from_ref::<Self>(self).cast::<T>()
194 }
195
196 pub const fn as_mut_ptr(&mut self) -> *mut T {
198 ptr::from_mut::<Self>(self).cast::<T>()
199 }
200
201 #[inline]
203 pub fn iter(&self) -> Iter<'_, T> {
204 self.as_slice().iter()
205 }
206
207 #[inline]
209 pub fn iter_mut(&mut self) -> IterMut<'_, T> {
210 self.0.as_mut().iter_mut()
211 }
212
213 pub fn map<F, O>(self, f: F) -> Array<O, U>
216 where
217 F: FnMut(T) -> O,
218 {
219 self.into_iter().map(f).collect()
220 }
221
222 #[inline]
224 pub fn concat<N>(self, other: Array<T, N>) -> Array<T, Sum<U, N>>
225 where
226 N: ArraySize,
227 U: Add<N>,
228 Sum<U, N>: ArraySize,
229 {
230 let mut c = Array::uninit();
231 let (left, right) = c.split_at_mut(self.len());
232 for (val, dst) in self.into_iter().zip(left) {
233 dst.write(val);
234 }
235 for (val, dst) in other.into_iter().zip(right) {
236 dst.write(val);
237 }
238 unsafe { c.assume_init() }
240 }
241
242 #[inline]
246 pub fn split<N>(self) -> SplitResult<T, U, N>
247 where
248 U: Sub<N>,
249 N: ArraySize,
250 Diff<U, N>: ArraySize,
251 {
252 unsafe {
253 let array = ManuallyDrop::new(self);
254 let head = ptr::read(array.as_ptr().cast());
255 let tail = ptr::read(array.as_ptr().add(N::USIZE).cast());
256 (head, tail)
257 }
258 }
259
260 #[inline]
262 pub fn split_ref<N>(&self) -> SplitRefResult<'_, T, U, N>
263 where
264 U: Sub<N>,
265 N: ArraySize,
266 Diff<U, N>: ArraySize,
267 {
268 unsafe {
269 let array_ptr = self.as_ptr();
270 let head = &*array_ptr.cast();
271 let tail = &*array_ptr.add(N::USIZE).cast();
272 (head, tail)
273 }
274 }
275
276 #[inline]
278 pub fn split_ref_mut<N>(&mut self) -> SplitRefMutResult<'_, T, U, N>
279 where
280 U: Sub<N>,
281 N: ArraySize,
282 Diff<U, N>: ArraySize,
283 {
284 unsafe {
285 let array_ptr = self.as_mut_ptr();
286 let head = &mut *array_ptr.cast();
287 let tail = &mut *array_ptr.add(N::USIZE).cast();
288 (head, tail)
289 }
290 }
291
292 #[inline]
296 #[must_use]
297 pub const fn slice_as_array(slice: &[T]) -> Option<&Self> {
298 if slice.len() == U::USIZE {
299 unsafe { Some(&*slice.as_ptr().cast()) }
303 } else {
304 None
305 }
306 }
307
308 #[inline]
313 #[must_use]
314 pub const fn slice_as_mut_array(slice: &mut [T]) -> Option<&mut Self> {
315 if slice.len() == U::USIZE {
316 unsafe { Some(&mut *slice.as_mut_ptr().cast()) }
320 } else {
321 None
322 }
323 }
324
325 #[allow(clippy::arithmetic_side_effects)]
331 #[inline]
332 pub const fn slice_as_chunks(buf: &[T]) -> (&[Self], &[T]) {
333 assert!(U::USIZE != 0, "chunk size must be non-zero");
334 let chunks_len = buf.len() / U::USIZE;
338 let tail_pos = U::USIZE * chunks_len;
339 let tail_len = buf.len() - tail_pos;
340 unsafe {
341 let ptr = buf.as_ptr();
342 let chunks = slice::from_raw_parts(ptr.cast(), chunks_len);
343 let tail = slice::from_raw_parts(ptr.add(tail_pos), tail_len);
344 (chunks, tail)
345 }
346 }
347
348 #[allow(clippy::arithmetic_side_effects)]
354 #[inline]
355 pub const fn slice_as_chunks_mut(buf: &mut [T]) -> (&mut [Self], &mut [T]) {
356 assert!(U::USIZE != 0, "chunk size must be non-zero");
357 let chunks_len = buf.len() / U::USIZE;
361 let tail_pos = U::USIZE * chunks_len;
362 let tail_len = buf.len() - tail_pos;
363 unsafe {
364 let ptr = buf.as_mut_ptr();
365 let chunks = slice::from_raw_parts_mut(ptr.cast(), chunks_len);
366 let tail = slice::from_raw_parts_mut(ptr.add(tail_pos), tail_len);
367 (chunks, tail)
368 }
369 }
370
371 #[inline]
376 pub const fn slice_as_flattened(slice: &[Self]) -> &[T] {
377 let len = slice
378 .len()
379 .checked_mul(U::USIZE)
380 .expect("slice len overflow");
381
382 unsafe { slice::from_raw_parts(slice.as_ptr().cast(), len) }
385 }
386
387 #[inline]
392 pub const fn slice_as_flattened_mut(slice: &mut [Self]) -> &mut [T] {
393 let len = slice
394 .len()
395 .checked_mul(U::USIZE)
396 .expect("slice len overflow");
397
398 unsafe { slice::from_raw_parts_mut(slice.as_mut_ptr().cast(), len) }
401 }
402}
403
404impl<T> Array<T, U1> {
405 pub const fn from_ref(r: &T) -> &Self {
407 Self::cast_from_core(core::array::from_ref(r))
408 }
409
410 pub const fn from_mut(r: &mut T) -> &mut Self {
413 Self::cast_from_core_mut(core::array::from_mut(r))
414 }
415}
416
417impl<T, U, V> Array<Array<T, U>, V>
418where
419 U: ArraySize,
420 V: ArraySize,
421{
422 pub const fn as_flattened(&self) -> &[T] {
453 Array::slice_as_flattened(self.as_slice())
454 }
455
456 pub const fn as_flattened_mut(&mut self) -> &mut [T] {
482 Array::slice_as_flattened_mut(self.as_mut_slice())
483 }
484}
485
486impl<T, U, const N: usize> Array<T, U>
488where
489 U: ArraySize<ArrayType<T> = [T; N]>,
490{
491 #[inline]
493 pub const fn cast_from_core(array_ref: &[T; N]) -> &Self {
494 unsafe { &*array_ref.as_ptr().cast() }
496 }
497
498 #[inline]
500 pub const fn cast_from_core_mut(array_ref: &mut [T; N]) -> &mut Self {
501 unsafe { &mut *array_ref.as_mut_ptr().cast() }
503 }
504
505 #[inline]
507 pub const fn cast_slice_from_core(slice: &[[T; N]]) -> &[Self] {
508 unsafe { slice::from_raw_parts(slice.as_ptr().cast(), slice.len()) }
510 }
511
512 #[inline]
514 pub const fn cast_slice_from_core_mut(slice: &mut [[T; N]]) -> &mut [Self] {
515 unsafe { slice::from_raw_parts_mut(slice.as_mut_ptr().cast(), slice.len()) }
517 }
518
519 #[inline]
521 pub const fn cast_slice_to_core(slice: &[Self]) -> &[[T; N]] {
522 unsafe { slice::from_raw_parts(slice.as_ptr().cast(), slice.len()) }
524 }
525
526 #[inline]
528 pub const fn cast_slice_to_core_mut(slice: &mut [Self]) -> &mut [[T; N]] {
529 unsafe { slice::from_raw_parts_mut(slice.as_mut_ptr().cast(), slice.len()) }
531 }
532}
533
534impl<T, U> Array<MaybeUninit<T>, U>
535where
536 U: ArraySize,
537{
538 #[must_use]
540 pub const fn uninit() -> Array<MaybeUninit<T>, U> {
541 #[allow(clippy::uninit_assumed_init)]
550 Self(unsafe { MaybeUninit::uninit().assume_init() })
551 }
552
553 #[inline]
560 pub unsafe fn assume_init(self) -> Array<T, U> {
561 unsafe {
562 mem::transmute_copy(&self)
574 }
575 }
576}
577
578impl<T, U> AsRef<Array<T, U>> for Array<T, U>
579where
580 U: ArraySize,
581{
582 #[inline]
583 fn as_ref(&self) -> &Self {
584 self
585 }
586}
587
588impl<T, U> AsRef<[T]> for Array<T, U>
589where
590 U: ArraySize,
591{
592 #[inline]
593 fn as_ref(&self) -> &[T] {
594 self.0.as_ref()
595 }
596}
597
598impl<T, U, const N: usize> AsRef<[T; N]> for Array<T, U>
599where
600 U: ArraySize<ArrayType<T> = [T; N]>,
601{
602 #[inline]
603 fn as_ref(&self) -> &[T; N] {
604 &self.0
605 }
606}
607
608impl<T, U> AsMut<Array<T, U>> for Array<T, U>
609where
610 U: ArraySize,
611{
612 #[inline]
613 fn as_mut(&mut self) -> &mut Self {
614 self
615 }
616}
617
618impl<T, U> AsMut<[T]> for Array<T, U>
619where
620 U: ArraySize,
621{
622 #[inline]
623 fn as_mut(&mut self) -> &mut [T] {
624 self.0.as_mut()
625 }
626}
627
628impl<T, U, const N: usize> AsMut<[T; N]> for Array<T, U>
629where
630 U: ArraySize<ArrayType<T> = [T; N]>,
631{
632 #[inline]
633 fn as_mut(&mut self) -> &mut [T; N] {
634 &mut self.0
635 }
636}
637
638impl<T, U> Borrow<[T]> for Array<T, U>
639where
640 U: ArraySize,
641{
642 #[inline]
643 fn borrow(&self) -> &[T] {
644 self.0.as_ref()
645 }
646}
647
648impl<T, U, const N: usize> Borrow<[T; N]> for Array<T, U>
649where
650 U: ArraySize<ArrayType<T> = [T; N]>,
651{
652 #[inline]
653 fn borrow(&self) -> &[T; N] {
654 &self.0
655 }
656}
657
658impl<T, U> BorrowMut<[T]> for Array<T, U>
659where
660 U: ArraySize,
661{
662 #[inline]
663 fn borrow_mut(&mut self) -> &mut [T] {
664 self.0.as_mut()
665 }
666}
667
668impl<T, U, const N: usize> BorrowMut<[T; N]> for Array<T, U>
669where
670 U: ArraySize<ArrayType<T> = [T; N]>,
671{
672 #[inline]
673 fn borrow_mut(&mut self) -> &mut [T; N] {
674 &mut self.0
675 }
676}
677
678impl<T, U> Clone for Array<T, U>
679where
680 T: Clone,
681 U: ArraySize,
682{
683 #[inline]
684 fn clone(&self) -> Self {
685 Self::from_fn(|n| self.0.as_ref()[n].clone())
686 }
687}
688
689impl<T, U> Copy for Array<T, U>
690where
691 T: Copy,
692 U: ArraySize,
693 U::ArrayType<T>: Copy,
694{
695}
696
697impl<T, U> Debug for Array<T, U>
698where
699 T: Debug,
700 U: ArraySize,
701{
702 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
703 f.debug_tuple("Array").field(&self.0.as_ref()).finish()
704 }
705}
706
707impl<T, U> Default for Array<T, U>
708where
709 T: Default,
710 U: ArraySize,
711{
712 #[inline]
713 fn default() -> Self {
714 Self::from_fn(|_| Default::default())
715 }
716}
717
718impl<T, U> Deref for Array<T, U>
719where
720 U: ArraySize,
721{
722 type Target = [T];
723
724 #[inline]
725 fn deref(&self) -> &[T] {
726 self.0.as_ref()
727 }
728}
729
730impl<T, U> DerefMut for Array<T, U>
731where
732 U: ArraySize,
733{
734 #[inline]
735 fn deref_mut(&mut self) -> &mut [T] {
736 self.0.as_mut()
737 }
738}
739
740impl<T, U> Eq for Array<T, U>
741where
742 T: Eq,
743 U: ArraySize,
744{
745}
746
747impl<T, U, const N: usize> From<[T; N]> for Array<T, U>
748where
749 U: ArraySize<ArrayType<T> = [T; N]>,
750{
751 #[inline]
752 fn from(arr: [T; N]) -> Array<T, U> {
753 Array(arr)
754 }
755}
756
757impl<T, U, const N: usize> From<Array<T, U>> for [T; N]
758where
759 U: ArraySize<ArrayType<T> = [T; N]>,
760{
761 #[inline]
762 fn from(arr: Array<T, U>) -> [T; N] {
763 arr.0
764 }
765}
766
767impl<'a, T, U, const N: usize> From<&'a [T; N]> for &'a Array<T, U>
768where
769 U: ArraySize<ArrayType<T> = [T; N]>,
770{
771 #[inline]
772 fn from(array_ref: &'a [T; N]) -> &'a Array<T, U> {
773 Array::cast_from_core(array_ref)
774 }
775}
776
777impl<'a, T, U, const N: usize> From<&'a Array<T, U>> for &'a [T; N]
778where
779 U: ArraySize<ArrayType<T> = [T; N]>,
780{
781 #[inline]
782 fn from(array_ref: &'a Array<T, U>) -> &'a [T; N] {
783 array_ref.as_ref()
784 }
785}
786
787impl<'a, T, U, const N: usize> From<&'a mut [T; N]> for &'a mut Array<T, U>
788where
789 U: ArraySize<ArrayType<T> = [T; N]>,
790{
791 #[inline]
792 fn from(array_ref: &'a mut [T; N]) -> &'a mut Array<T, U> {
793 Array::cast_from_core_mut(array_ref)
794 }
795}
796
797impl<'a, T, U, const N: usize> From<&'a mut Array<T, U>> for &'a mut [T; N]
798where
799 U: ArraySize<ArrayType<T> = [T; N]>,
800{
801 #[inline]
802 fn from(array_ref: &'a mut Array<T, U>) -> &'a mut [T; N] {
803 array_ref.as_mut()
804 }
805}
806
807#[cfg(feature = "alloc")]
808impl<T, U> From<Array<T, U>> for alloc::boxed::Box<[T]>
809where
810 U: ArraySize,
811{
812 #[inline]
813 fn from(array: Array<T, U>) -> alloc::boxed::Box<[T]> {
814 array.into_iter().collect()
815 }
816}
817
818#[cfg(feature = "alloc")]
819impl<T, U> From<&Array<T, U>> for alloc::boxed::Box<[T]>
820where
821 T: Clone,
822 U: ArraySize,
823{
824 #[inline]
825 fn from(array: &Array<T, U>) -> alloc::boxed::Box<[T]> {
826 array.as_slice().into()
827 }
828}
829
830#[cfg(feature = "alloc")]
831impl<T, U> From<Array<T, U>> for alloc::vec::Vec<T>
832where
833 U: ArraySize,
834{
835 #[inline]
836 fn from(array: Array<T, U>) -> alloc::vec::Vec<T> {
837 array.into_iter().collect()
838 }
839}
840
841#[cfg(feature = "alloc")]
842impl<T, U> From<&Array<T, U>> for alloc::vec::Vec<T>
843where
844 T: Clone,
845 U: ArraySize,
846{
847 #[inline]
848 fn from(array: &Array<T, U>) -> alloc::vec::Vec<T> {
849 array.as_slice().into()
850 }
851}
852
853impl<T, U> Hash for Array<T, U>
854where
855 T: Hash,
856 U: ArraySize,
857{
858 #[inline]
859 fn hash<H: Hasher>(&self, state: &mut H) {
860 self.0.as_ref().hash(state);
861 }
862}
863
864impl<T, I, U> Index<I> for Array<T, U>
865where
866 [T]: Index<I>,
867 U: ArraySize,
868{
869 type Output = <[T] as Index<I>>::Output;
870
871 #[inline]
872 fn index(&self, index: I) -> &Self::Output {
873 Index::index(self.as_slice(), index)
874 }
875}
876
877impl<T, I, U> IndexMut<I> for Array<T, U>
878where
879 [T]: IndexMut<I>,
880 U: ArraySize,
881{
882 #[inline]
883 fn index_mut(&mut self, index: I) -> &mut Self::Output {
884 IndexMut::index_mut(self.as_mut_slice(), index)
885 }
886}
887
888impl<T, U> PartialEq for Array<T, U>
889where
890 T: PartialEq,
891 U: ArraySize,
892{
893 #[inline]
894 fn eq(&self, other: &Self) -> bool {
895 self.0.as_ref().eq(other.0.as_ref())
896 }
897}
898
899impl<T, U, const N: usize> PartialEq<[T; N]> for Array<T, U>
900where
901 T: PartialEq,
902 U: ArraySize<ArrayType<T> = [T; N]>,
903{
904 #[inline]
905 fn eq(&self, other: &[T; N]) -> bool {
906 self.0.eq(other)
907 }
908}
909
910impl<T, U, const N: usize> PartialEq<Array<T, U>> for [T; N]
911where
912 T: PartialEq,
913 U: ArraySize<ArrayType<T> = [T; N]>,
914{
915 #[inline]
916 fn eq(&self, other: &Array<T, U>) -> bool {
917 self.eq(&other.0)
918 }
919}
920
921impl<T, U> PartialOrd for Array<T, U>
922where
923 T: PartialOrd,
924 U: ArraySize,
925{
926 #[inline]
927 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
928 self.0.as_ref().partial_cmp(other.0.as_ref())
929 }
930}
931
932impl<T, U> Ord for Array<T, U>
933where
934 T: Ord,
935 U: ArraySize,
936{
937 #[inline]
938 fn cmp(&self, other: &Self) -> Ordering {
939 self.0.as_ref().cmp(other.0.as_ref())
940 }
941}
942
943unsafe impl<T, U: ArraySize> Send for Array<T, U> where T: Send {}
946
947unsafe impl<T, U: ArraySize> Sync for Array<T, U> where T: Sync {}
950
951impl<'a, T, U> TryFrom<&'a [T]> for &'a Array<T, U>
952where
953 U: ArraySize,
954{
955 type Error = TryFromSliceError;
956
957 #[inline]
958 fn try_from(slice: &'a [T]) -> Result<Self, TryFromSliceError> {
959 check_slice_length::<T, U>(slice)?;
960
961 Ok(unsafe { &*slice.as_ptr().cast() })
964 }
965}
966
967impl<'a, T, U> TryFrom<&'a mut [T]> for &'a mut Array<T, U>
968where
969 U: ArraySize,
970{
971 type Error = TryFromSliceError;
972
973 #[inline]
974 fn try_from(slice: &'a mut [T]) -> Result<Self, TryFromSliceError> {
975 check_slice_length::<T, U>(slice)?;
976
977 Ok(unsafe { &mut *slice.as_mut_ptr().cast() })
980 }
981}
982
983impl<'a, T, U> TryFrom<&'a [T]> for Array<T, U>
984where
985 Self: Clone,
986 U: ArraySize,
987{
988 type Error = TryFromSliceError;
989
990 #[inline]
991 fn try_from(slice: &'a [T]) -> Result<Array<T, U>, TryFromSliceError> {
992 <&'a Self>::try_from(slice).cloned()
993 }
994}
995
996#[cfg(feature = "alloc")]
997impl<T, U> TryFrom<alloc::boxed::Box<[T]>> for Array<T, U>
998where
999 Self: Clone,
1000 U: ArraySize,
1001{
1002 type Error = TryFromSliceError;
1003
1004 #[inline]
1005 fn try_from(b: alloc::boxed::Box<[T]>) -> Result<Self, TryFromSliceError> {
1006 Self::try_from(&*b)
1007 }
1008}
1009
1010#[cfg(feature = "alloc")]
1011impl<'a, T, U> TryFrom<&'a alloc::boxed::Box<[T]>> for Array<T, U>
1012where
1013 Self: Clone,
1014 U: ArraySize,
1015{
1016 type Error = TryFromSliceError;
1017
1018 #[inline]
1019 fn try_from(b: &'a alloc::boxed::Box<[T]>) -> Result<Self, TryFromSliceError> {
1020 Self::try_from(&**b)
1021 }
1022}
1023
1024#[cfg(feature = "alloc")]
1025impl<T, U> TryFrom<alloc::vec::Vec<T>> for Array<T, U>
1026where
1027 Self: Clone,
1028 U: ArraySize,
1029{
1030 type Error = TryFromSliceError;
1031
1032 #[inline]
1033 fn try_from(v: alloc::vec::Vec<T>) -> Result<Self, TryFromSliceError> {
1034 Self::try_from(v.as_slice())
1035 }
1036}
1037
1038#[cfg(feature = "alloc")]
1039impl<'a, T, U> TryFrom<&'a alloc::vec::Vec<T>> for Array<T, U>
1040where
1041 Self: Clone,
1042 U: ArraySize,
1043{
1044 type Error = TryFromSliceError;
1045
1046 #[inline]
1047 fn try_from(v: &'a alloc::vec::Vec<T>) -> Result<Self, TryFromSliceError> {
1048 Self::try_from(v.as_slice())
1049 }
1050}
1051
1052impl<T, U> Array<T, U>
1054where
1055 U: ArraySize,
1056{
1057 #[deprecated(since = "0.2.0", note = "use `TryFrom` instead")]
1063 #[inline]
1064 pub fn from_slice(slice: &[T]) -> &Self {
1065 slice.try_into().expect("slice length mismatch")
1066 }
1067
1068 #[deprecated(since = "0.2.0", note = "use `TryFrom` instead")]
1074 #[inline]
1075 pub fn from_mut_slice(slice: &mut [T]) -> &mut Self {
1076 slice.try_into().expect("slice length mismatch")
1077 }
1078
1079 #[deprecated(since = "0.2.0", note = "use `TryFrom` instead")]
1085 #[inline]
1086 pub fn clone_from_slice(slice: &[T]) -> Self
1087 where
1088 Self: Clone,
1089 {
1090 slice.try_into().expect("slice length mismatch")
1091 }
1092}
1093
1094#[cfg(feature = "arbitrary")]
1095impl<'a, T, U> Arbitrary<'a> for Array<T, U>
1096where
1097 T: Arbitrary<'a>,
1098 U: ArraySize,
1099{
1100 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
1101 Self::try_from_fn(|_n| Arbitrary::arbitrary(u))
1102 }
1103}
1104
1105#[cfg(feature = "bytemuck")]
1106unsafe impl<T, U> Pod for Array<T, U>
1107where
1108 T: Pod,
1109 U: ArraySize,
1110 U::ArrayType<T>: Copy,
1111{
1112}
1113
1114#[cfg(feature = "bytemuck")]
1115unsafe impl<T, U> Zeroable for Array<T, U>
1116where
1117 T: Zeroable,
1118 U: ArraySize,
1119{
1120}
1121
1122#[cfg(feature = "ctutils")]
1123impl<T, U> ctutils::CtAssign for Array<T, U>
1124where
1125 [T]: ctutils::CtAssign,
1126 U: ArraySize,
1127{
1128 #[inline]
1129 fn ct_assign(&mut self, other: &Self, choice: ctutils::Choice) {
1130 self.as_mut_slice().ct_assign(other.as_slice(), choice);
1131 }
1132}
1133
1134#[cfg(feature = "ctutils")]
1135impl<T, U> ctutils::CtSelect for Array<T, U>
1136where
1137 U: ArraySize,
1138 U::ArrayType<T>: ctutils::CtSelect,
1139{
1140 #[inline]
1141 fn ct_select(&self, other: &Self, choice: ctutils::Choice) -> Self {
1142 Self(self.0.ct_select(&other.0, choice))
1143 }
1144}
1145
1146#[cfg(feature = "ctutils")]
1147impl<T, U> ctutils::CtEq for Array<T, U>
1148where
1149 U: ArraySize,
1150 U::ArrayType<T>: ctutils::CtEq,
1151{
1152 #[inline]
1153 fn ct_eq(&self, other: &Self) -> ctutils::Choice {
1154 self.0.ct_eq(&other.0)
1155 }
1156}
1157
1158#[cfg(feature = "subtle")]
1159impl<T, U> subtle::ConditionallySelectable for Array<T, U>
1160where
1161 Self: Copy,
1162 T: subtle::ConditionallySelectable,
1163 U: ArraySize,
1164{
1165 #[inline]
1166 fn conditional_select(a: &Self, b: &Self, choice: subtle::Choice) -> Self {
1167 let mut output = *a;
1168 output.conditional_assign(b, choice);
1169 output
1170 }
1171
1172 fn conditional_assign(&mut self, other: &Self, choice: subtle::Choice) {
1173 for (a_i, b_i) in self.iter_mut().zip(other) {
1174 a_i.conditional_assign(b_i, choice);
1175 }
1176 }
1177}
1178
1179#[cfg(feature = "subtle")]
1180impl<T, U> subtle::ConstantTimeEq for Array<T, U>
1181where
1182 T: subtle::ConstantTimeEq,
1183 U: ArraySize,
1184{
1185 #[inline]
1186 fn ct_eq(&self, other: &Self) -> subtle::Choice {
1187 self.iter()
1188 .zip(other.iter())
1189 .fold(subtle::Choice::from(1), |acc, (a, b)| acc & a.ct_eq(b))
1190 }
1191}
1192
1193#[cfg(feature = "zeroize")]
1194impl<T, U> Zeroize for Array<T, U>
1195where
1196 T: Zeroize,
1197 U: ArraySize,
1198{
1199 #[inline]
1200 fn zeroize(&mut self) {
1201 self.0.as_mut().iter_mut().zeroize();
1202 }
1203}
1204
1205#[cfg(feature = "zeroize")]
1206impl<T, U> ZeroizeOnDrop for Array<T, U>
1207where
1208 T: ZeroizeOnDrop,
1209 U: ArraySize,
1210{
1211}
1212
1213#[cfg_attr(debug_assertions, allow(clippy::panic_in_result_fn))]
1215fn check_slice_length<T, U: ArraySize>(slice: &[T]) -> Result<(), TryFromSliceError> {
1216 debug_assert_eq!(Array::<(), U>::default().len(), U::USIZE);
1217
1218 if slice.len() != U::USIZE {
1219 <&[T; 1]>::try_from([].as_slice())?;
1221
1222 #[cfg(debug_assertions)]
1223 unreachable!();
1224 }
1225
1226 Ok(())
1227}