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.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<[T]> for Array<T, U>
609where
610 U: ArraySize,
611{
612 #[inline]
613 fn as_mut(&mut self) -> &mut [T] {
614 self.0.as_mut()
615 }
616}
617
618impl<T, U, const N: usize> AsMut<[T; N]> for Array<T, U>
619where
620 U: ArraySize<ArrayType<T> = [T; N]>,
621{
622 #[inline]
623 fn as_mut(&mut self) -> &mut [T; N] {
624 &mut self.0
625 }
626}
627
628impl<T, U> Borrow<[T]> for Array<T, U>
629where
630 U: ArraySize,
631{
632 #[inline]
633 fn borrow(&self) -> &[T] {
634 self.0.as_ref()
635 }
636}
637
638impl<T, U, const N: usize> Borrow<[T; N]> for Array<T, U>
639where
640 U: ArraySize<ArrayType<T> = [T; N]>,
641{
642 #[inline]
643 fn borrow(&self) -> &[T; N] {
644 &self.0
645 }
646}
647
648impl<T, U> BorrowMut<[T]> for Array<T, U>
649where
650 U: ArraySize,
651{
652 #[inline]
653 fn borrow_mut(&mut self) -> &mut [T] {
654 self.0.as_mut()
655 }
656}
657
658impl<T, U, const N: usize> BorrowMut<[T; N]> for Array<T, U>
659where
660 U: ArraySize<ArrayType<T> = [T; N]>,
661{
662 #[inline]
663 fn borrow_mut(&mut self) -> &mut [T; N] {
664 &mut self.0
665 }
666}
667
668impl<T, U> Clone for Array<T, U>
669where
670 T: Clone,
671 U: ArraySize,
672{
673 #[inline]
674 fn clone(&self) -> Self {
675 Self::from_fn(|n| self.0.as_ref()[n].clone())
676 }
677}
678
679impl<T, U> Copy for Array<T, U>
680where
681 T: Copy,
682 U: ArraySize,
683 U::ArrayType<T>: Copy,
684{
685}
686
687impl<T, U> Debug for Array<T, U>
688where
689 T: Debug,
690 U: ArraySize,
691{
692 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
693 f.debug_tuple("Array").field(&self.0.as_ref()).finish()
694 }
695}
696
697impl<T, U> Default for Array<T, U>
698where
699 T: Default,
700 U: ArraySize,
701{
702 #[inline]
703 fn default() -> Self {
704 Self::from_fn(|_| Default::default())
705 }
706}
707
708impl<T, U> Deref for Array<T, U>
709where
710 U: ArraySize,
711{
712 type Target = [T];
713
714 #[inline]
715 fn deref(&self) -> &[T] {
716 self.0.as_ref()
717 }
718}
719
720impl<T, U> DerefMut for Array<T, U>
721where
722 U: ArraySize,
723{
724 #[inline]
725 fn deref_mut(&mut self) -> &mut [T] {
726 self.0.as_mut()
727 }
728}
729
730impl<T, U> Eq for Array<T, U>
731where
732 T: Eq,
733 U: ArraySize,
734{
735}
736
737impl<T, U, const N: usize> From<[T; N]> for Array<T, U>
738where
739 U: ArraySize<ArrayType<T> = [T; N]>,
740{
741 #[inline]
742 fn from(arr: [T; N]) -> Array<T, U> {
743 Array(arr)
744 }
745}
746
747impl<T, U, const N: usize> From<Array<T, U>> for [T; N]
748where
749 U: ArraySize<ArrayType<T> = [T; N]>,
750{
751 #[inline]
752 fn from(arr: Array<T, U>) -> [T; N] {
753 arr.0
754 }
755}
756
757impl<'a, T, U, const N: usize> From<&'a [T; N]> for &'a Array<T, U>
758where
759 U: ArraySize<ArrayType<T> = [T; N]>,
760{
761 #[inline]
762 fn from(array_ref: &'a [T; N]) -> &'a Array<T, U> {
763 Array::cast_from_core(array_ref)
764 }
765}
766
767impl<'a, T, U, const N: usize> From<&'a Array<T, U>> for &'a [T; N]
768where
769 U: ArraySize<ArrayType<T> = [T; N]>,
770{
771 #[inline]
772 fn from(array_ref: &'a Array<T, U>) -> &'a [T; N] {
773 array_ref.as_ref()
774 }
775}
776
777impl<'a, T, U, const N: usize> From<&'a mut [T; N]> for &'a mut Array<T, U>
778where
779 U: ArraySize<ArrayType<T> = [T; N]>,
780{
781 #[inline]
782 fn from(array_ref: &'a mut [T; N]) -> &'a mut Array<T, U> {
783 Array::cast_from_core_mut(array_ref)
784 }
785}
786
787impl<'a, T, U, const N: usize> From<&'a mut Array<T, U>> for &'a mut [T; N]
788where
789 U: ArraySize<ArrayType<T> = [T; N]>,
790{
791 #[inline]
792 fn from(array_ref: &'a mut Array<T, U>) -> &'a mut [T; N] {
793 array_ref.as_mut()
794 }
795}
796
797#[cfg(feature = "alloc")]
798impl<T, U> From<Array<T, U>> for alloc::boxed::Box<[T]>
799where
800 U: ArraySize,
801{
802 #[inline]
803 fn from(array: Array<T, U>) -> alloc::boxed::Box<[T]> {
804 array.into_iter().collect()
805 }
806}
807
808#[cfg(feature = "alloc")]
809impl<T, U> From<&Array<T, U>> for alloc::boxed::Box<[T]>
810where
811 T: Clone,
812 U: ArraySize,
813{
814 #[inline]
815 fn from(array: &Array<T, U>) -> alloc::boxed::Box<[T]> {
816 array.as_slice().into()
817 }
818}
819
820#[cfg(feature = "alloc")]
821impl<T, U> From<Array<T, U>> for alloc::vec::Vec<T>
822where
823 U: ArraySize,
824{
825 #[inline]
826 fn from(array: Array<T, U>) -> alloc::vec::Vec<T> {
827 array.into_iter().collect()
828 }
829}
830
831#[cfg(feature = "alloc")]
832impl<T, U> From<&Array<T, U>> for alloc::vec::Vec<T>
833where
834 T: Clone,
835 U: ArraySize,
836{
837 #[inline]
838 fn from(array: &Array<T, U>) -> alloc::vec::Vec<T> {
839 array.as_slice().into()
840 }
841}
842
843impl<T, U> Hash for Array<T, U>
844where
845 T: Hash,
846 U: ArraySize,
847{
848 #[inline]
849 fn hash<H: Hasher>(&self, state: &mut H) {
850 self.0.as_ref().hash(state);
851 }
852}
853
854impl<T, I, U> Index<I> for Array<T, U>
855where
856 [T]: Index<I>,
857 U: ArraySize,
858{
859 type Output = <[T] as Index<I>>::Output;
860
861 #[inline]
862 fn index(&self, index: I) -> &Self::Output {
863 Index::index(self.as_slice(), index)
864 }
865}
866
867impl<T, I, U> IndexMut<I> for Array<T, U>
868where
869 [T]: IndexMut<I>,
870 U: ArraySize,
871{
872 #[inline]
873 fn index_mut(&mut self, index: I) -> &mut Self::Output {
874 IndexMut::index_mut(self.as_mut_slice(), index)
875 }
876}
877
878impl<T, U> PartialEq for Array<T, U>
879where
880 T: PartialEq,
881 U: ArraySize,
882{
883 #[inline]
884 fn eq(&self, other: &Self) -> bool {
885 self.0.as_ref().eq(other.0.as_ref())
886 }
887}
888
889impl<T, U, const N: usize> PartialEq<[T; N]> for Array<T, U>
890where
891 T: PartialEq,
892 U: ArraySize<ArrayType<T> = [T; N]>,
893{
894 #[inline]
895 fn eq(&self, other: &[T; N]) -> bool {
896 self.0.eq(other)
897 }
898}
899
900impl<T, U, const N: usize> PartialEq<Array<T, U>> for [T; N]
901where
902 T: PartialEq,
903 U: ArraySize<ArrayType<T> = [T; N]>,
904{
905 #[inline]
906 fn eq(&self, other: &Array<T, U>) -> bool {
907 self.eq(&other.0)
908 }
909}
910
911impl<T, U> PartialOrd for Array<T, U>
912where
913 T: PartialOrd,
914 U: ArraySize,
915{
916 #[inline]
917 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
918 self.0.as_ref().partial_cmp(other.0.as_ref())
919 }
920}
921
922impl<T, U> Ord for Array<T, U>
923where
924 T: Ord,
925 U: ArraySize,
926{
927 #[inline]
928 fn cmp(&self, other: &Self) -> Ordering {
929 self.0.as_ref().cmp(other.0.as_ref())
930 }
931}
932
933unsafe impl<T, U: ArraySize> Send for Array<T, U> where T: Send {}
936
937unsafe impl<T, U: ArraySize> Sync for Array<T, U> where T: Sync {}
940
941impl<'a, T, U> TryFrom<&'a [T]> for &'a Array<T, U>
942where
943 U: ArraySize,
944{
945 type Error = TryFromSliceError;
946
947 #[inline]
948 fn try_from(slice: &'a [T]) -> Result<Self, TryFromSliceError> {
949 check_slice_length::<T, U>(slice)?;
950
951 Ok(unsafe { &*slice.as_ptr().cast() })
954 }
955}
956
957impl<'a, T, U> TryFrom<&'a mut [T]> for &'a mut Array<T, U>
958where
959 U: ArraySize,
960{
961 type Error = TryFromSliceError;
962
963 #[inline]
964 fn try_from(slice: &'a mut [T]) -> Result<Self, TryFromSliceError> {
965 check_slice_length::<T, U>(slice)?;
966
967 Ok(unsafe { &mut *slice.as_mut_ptr().cast() })
970 }
971}
972
973impl<'a, T, U> TryFrom<&'a [T]> for Array<T, U>
974where
975 Self: Clone,
976 U: ArraySize,
977{
978 type Error = TryFromSliceError;
979
980 #[inline]
981 fn try_from(slice: &'a [T]) -> Result<Array<T, U>, TryFromSliceError> {
982 <&'a Self>::try_from(slice).cloned()
983 }
984}
985
986#[cfg(feature = "alloc")]
987impl<T, U> TryFrom<alloc::boxed::Box<[T]>> for Array<T, U>
988where
989 Self: Clone,
990 U: ArraySize,
991{
992 type Error = TryFromSliceError;
993
994 #[inline]
995 fn try_from(b: alloc::boxed::Box<[T]>) -> Result<Self, TryFromSliceError> {
996 Self::try_from(&*b)
997 }
998}
999
1000#[cfg(feature = "alloc")]
1001impl<'a, T, U> TryFrom<&'a alloc::boxed::Box<[T]>> for Array<T, U>
1002where
1003 Self: Clone,
1004 U: ArraySize,
1005{
1006 type Error = TryFromSliceError;
1007
1008 #[inline]
1009 fn try_from(b: &'a alloc::boxed::Box<[T]>) -> Result<Self, TryFromSliceError> {
1010 Self::try_from(&**b)
1011 }
1012}
1013
1014#[cfg(feature = "alloc")]
1015impl<T, U> TryFrom<alloc::vec::Vec<T>> for Array<T, U>
1016where
1017 Self: Clone,
1018 U: ArraySize,
1019{
1020 type Error = TryFromSliceError;
1021
1022 #[inline]
1023 fn try_from(v: alloc::vec::Vec<T>) -> Result<Self, TryFromSliceError> {
1024 Self::try_from(v.as_slice())
1025 }
1026}
1027
1028#[cfg(feature = "alloc")]
1029impl<'a, T, U> TryFrom<&'a alloc::vec::Vec<T>> for Array<T, U>
1030where
1031 Self: Clone,
1032 U: ArraySize,
1033{
1034 type Error = TryFromSliceError;
1035
1036 #[inline]
1037 fn try_from(v: &'a alloc::vec::Vec<T>) -> Result<Self, TryFromSliceError> {
1038 Self::try_from(v.as_slice())
1039 }
1040}
1041
1042impl<T, U> Array<T, U>
1044where
1045 U: ArraySize,
1046{
1047 #[deprecated(since = "0.2.0", note = "use `TryFrom` instead")]
1053 #[inline]
1054 pub fn from_slice(slice: &[T]) -> &Self {
1055 slice.try_into().expect("slice length mismatch")
1056 }
1057
1058 #[deprecated(since = "0.2.0", note = "use `TryFrom` instead")]
1064 #[inline]
1065 pub fn from_mut_slice(slice: &mut [T]) -> &mut Self {
1066 slice.try_into().expect("slice length mismatch")
1067 }
1068
1069 #[deprecated(since = "0.2.0", note = "use `TryFrom` instead")]
1075 #[inline]
1076 pub fn clone_from_slice(slice: &[T]) -> Self
1077 where
1078 Self: Clone,
1079 {
1080 slice.try_into().expect("slice length mismatch")
1081 }
1082}
1083
1084#[cfg(feature = "arbitrary")]
1085impl<'a, T, U> Arbitrary<'a> for Array<T, U>
1086where
1087 T: Arbitrary<'a>,
1088 U: ArraySize,
1089{
1090 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
1091 Self::try_from_fn(|_n| Arbitrary::arbitrary(u))
1092 }
1093}
1094
1095#[cfg(feature = "bytemuck")]
1096unsafe impl<T, U> Pod for Array<T, U>
1097where
1098 T: Pod,
1099 U: ArraySize,
1100 U::ArrayType<T>: Copy,
1101{
1102}
1103
1104#[cfg(feature = "bytemuck")]
1105unsafe impl<T, U> Zeroable for Array<T, U>
1106where
1107 T: Zeroable,
1108 U: ArraySize,
1109{
1110}
1111
1112#[cfg(feature = "ctutils")]
1113impl<T, U> ctutils::CtAssign for Array<T, U>
1114where
1115 [T]: ctutils::CtAssign,
1116 U: ArraySize,
1117{
1118 #[inline]
1119 fn ct_assign(&mut self, other: &Self, choice: ctutils::Choice) {
1120 self.as_mut_slice().ct_assign(other.as_slice(), choice);
1121 }
1122}
1123
1124#[cfg(feature = "ctutils")]
1125impl<T, U> ctutils::CtSelect for Array<T, U>
1126where
1127 U: ArraySize,
1128 U::ArrayType<T>: ctutils::CtSelect,
1129{
1130 #[inline]
1131 fn ct_select(&self, other: &Self, choice: ctutils::Choice) -> Self {
1132 Self(self.0.ct_select(&other.0, choice))
1133 }
1134}
1135
1136#[cfg(feature = "ctutils")]
1137impl<T, U> ctutils::CtEq for Array<T, U>
1138where
1139 U: ArraySize,
1140 U::ArrayType<T>: ctutils::CtEq,
1141{
1142 #[inline]
1143 fn ct_eq(&self, other: &Self) -> ctutils::Choice {
1144 self.0.ct_eq(&other.0)
1145 }
1146}
1147
1148#[cfg(feature = "subtle")]
1149impl<T, U> subtle::ConditionallySelectable for Array<T, U>
1150where
1151 Self: Copy,
1152 T: subtle::ConditionallySelectable,
1153 U: ArraySize,
1154{
1155 #[inline]
1156 fn conditional_select(a: &Self, b: &Self, choice: subtle::Choice) -> Self {
1157 let mut output = *a;
1158 output.conditional_assign(b, choice);
1159 output
1160 }
1161
1162 fn conditional_assign(&mut self, other: &Self, choice: subtle::Choice) {
1163 for (a_i, b_i) in self.iter_mut().zip(other) {
1164 a_i.conditional_assign(b_i, choice);
1165 }
1166 }
1167}
1168
1169#[cfg(feature = "subtle")]
1170impl<T, U> subtle::ConstantTimeEq for Array<T, U>
1171where
1172 T: subtle::ConstantTimeEq,
1173 U: ArraySize,
1174{
1175 #[inline]
1176 fn ct_eq(&self, other: &Self) -> subtle::Choice {
1177 self.iter()
1178 .zip(other.iter())
1179 .fold(subtle::Choice::from(1), |acc, (a, b)| acc & a.ct_eq(b))
1180 }
1181}
1182
1183#[cfg(feature = "zeroize")]
1184impl<T, U> Zeroize for Array<T, U>
1185where
1186 T: Zeroize,
1187 U: ArraySize,
1188{
1189 #[inline]
1190 fn zeroize(&mut self) {
1191 self.0.as_mut().iter_mut().zeroize();
1192 }
1193}
1194
1195#[cfg(feature = "zeroize")]
1196impl<T, U> ZeroizeOnDrop for Array<T, U>
1197where
1198 T: ZeroizeOnDrop,
1199 U: ArraySize,
1200{
1201}
1202
1203#[cfg_attr(debug_assertions, allow(clippy::panic_in_result_fn))]
1205fn check_slice_length<T, U: ArraySize>(slice: &[T]) -> Result<(), TryFromSliceError> {
1206 debug_assert_eq!(Array::<(), U>::default().len(), U::USIZE);
1207
1208 if slice.len() != U::USIZE {
1209 <&[T; 1]>::try_from([].as_slice())?;
1211
1212 #[cfg(debug_assertions)]
1213 unreachable!();
1214 }
1215
1216 Ok(())
1217}