Skip to content

Commit

Permalink
Impl Default manually
Browse files Browse the repository at this point in the history
  • Loading branch information
est31 committed Mar 4, 2023
1 parent 33ef73f commit dacc6a7
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 4 deletions.
28 changes: 26 additions & 2 deletions src/array.rs
Original file line number Diff line number Diff line change
@@ -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};

Expand All @@ -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<T, const N: usize>(pub [T; N]);

impl<'de, T: Deserialize<'de>, const N: usize> Deserialize<'de> for Array<T, N> {
Expand All @@ -34,6 +35,29 @@ impl<'de, T: Deserialize<'de>, const N: usize> Deserialize<'de> for Array<T, N>
}
}

impl<T: Default, const N: usize> Default for Array<T, N> {
fn default() -> Self {
// TODO use array::from_fn once the MSRV allows stuff from 1.63.0
let arr = {
let mut arr: PartiallyInitialized<T, N> =
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<T: Serialize, const N: usize> Serialize for Array<T, N> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
Expand Down
5 changes: 4 additions & 1 deletion src/const_generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ use core::result;
use serde::de::{Deserialize, Deserializer, Error, SeqAccess, Visitor};
use serde::ser::{Serialize, SerializeTuple, Serializer};

struct PartiallyInitialized<T, const N: usize>(Option<MaybeUninit<[T; N]>>, usize);
pub(crate) struct PartiallyInitialized<T, const N: usize>(
pub(crate) Option<MaybeUninit<[T; N]>>,
pub(crate) usize,
);

impl<T, const N: usize> Drop for PartiallyInitialized<T, N> {
fn drop(&mut self) {
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

0 comments on commit dacc6a7

Please sign in to comment.