diff --git a/src/array.rs b/src/array.rs index d02a6a9..04a4fd6 100644 --- a/src/array.rs +++ b/src/array.rs @@ -1,4 +1,6 @@ +use crate::const_generics::PartiallyInitialized; use crate::BigArray; +use core::mem::MaybeUninit; use core::ops::{Deref, DerefMut, Index, IndexMut}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; @@ -21,8 +23,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer}; /// } /// ``` #[repr(transparent)] -#[derive(PartialEq, Eq, PartialOrd, Ord, Hash] -#[derive(Copy, Clone, Default, Debug)] +#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Clone, Debug)] pub struct Array(pub [T; N]); impl<'de, T: Deserialize<'de>, const N: usize> Deserialize<'de> for Array { @@ -34,6 +35,29 @@ impl<'de, T: Deserialize<'de>, const N: usize> Deserialize<'de> for Array } } +impl Default for Array { + fn default() -> Self { + // TODO use array::from_fn once the MSRV allows stuff from 1.63.0 + let arr = { + let mut arr: PartiallyInitialized = + PartiallyInitialized(Some(MaybeUninit::uninit()), 0); + unsafe { + { + let p = arr.0.as_mut().unwrap(); + for i in 0..N { + let p = (p.as_mut_ptr() as *mut T).wrapping_add(i); + core::ptr::write(p, Default::default()); + arr.1 += 1; + } + } + let initialized = arr.0.take().unwrap().assume_init(); + initialized + } + }; + Self(arr) + } +} + impl Serialize for Array { fn serialize(&self, serializer: S) -> Result where diff --git a/src/const_generics.rs b/src/const_generics.rs index e3e73ef..c3ee9bc 100644 --- a/src/const_generics.rs +++ b/src/const_generics.rs @@ -5,7 +5,10 @@ use core::result; use serde::de::{Deserialize, Deserializer, Error, SeqAccess, Visitor}; use serde::ser::{Serialize, SerializeTuple, Serializer}; -struct PartiallyInitialized(Option>, usize); +pub(crate) struct PartiallyInitialized( + pub(crate) Option>, + pub(crate) usize, +); impl Drop for PartiallyInitialized { fn drop(&mut self) { diff --git a/src/lib.rs b/src/lib.rs index 4b0220f..b82c0cd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -48,6 +48,6 @@ fn test() { #![no_std] mod array; -mod const_generics; +pub(crate) mod const_generics; pub use array::Array; pub use const_generics::BigArray;