-
-
Notifications
You must be signed in to change notification settings - Fork 14.2k
Description
This is mostly an ideas test for potentially introducing a generic impl for Default over an array of any size, rather than just up to 32.
My current implementation does not, unfortunately, implement default for arrays at zero cost; but could be useful for further checks:
use ::core::mem::MaybeUninit;
#[derive(Copy, Clone, Debug)]
struct ImplDefaultConstArray<T: Default, const N: usize> {
arr: MaybeUninit<[T; N]>,
idx: usize,
}
unsafe impl<T: Default, const N: usize> Drop for ImplDefaultConstArray<T, { N }> {
fn drop(&mut self) {
let _assigned = self.arr[..self.idx];
// let it drop normally
}
}
impl<T: Default, const N: usize> Default for [T; N] {
fn default() -> Self {
let uninit = ImplDefaultConstArray {
arr: MaybeUninit::uninit(),
idx: 0,
};
while uninit.idx < N {
uninit.arr[uninit.idx] = T::default();
uninit.idx += 1;
}
unsafe { uninit.arr.assume_init() }
}
}Unfortunately I believe this currently is an erroneous implementation, and has other issues regarding the real cost of it.
This could also be implemented in a less technical way if FromIterator on arrays stabilises, or rather a TryFromIterator implementation detailed below arises (note the try_collect)
use ::core::iter;
impl<T: Default, const N: usize> Default for [T; N]
fn default() -> Self {
#[cfg(feature = "impl_take_const")]
iter::repeat_with(T::default)
.take(N)
.try_collect()
.unwrap()
#[cfg(not(feature = "impl_take_const"))]
{
let mut idx = 0;
iter::from_fn(|| if idx < N {
*idx += 1;
Some(T::default())
} else {
None
})
.try_collect()
.unwrap()
}
}
}Or the original code could be a part of a generic implementation of FromIterator, or a potential trait TryFromIterator where type Error is of type TryFromSliceError, or a similarly zero-sized TryFromIteratorError; and a further is added:
impl<T: FromIterator, I> TryFromIterator<Item = I> for T {
type Error = !;
fn try_from_iter<Iter: Iterator<Item = I>(iter: Iter) -> Result<Self, Self::Error> {
Ok(T::from_iter(iter))
}
}... I thank you for your time.
p.s: I also should really stop writing these so early... and need to adopt more official language in this circumstance. If someone can write this up as a feature request or PR more officially, that'd be amazing. Thank you.