@@ -1085,6 +1085,93 @@ pub fn uninit<T, E>() -> impl Init<MaybeUninit<T>, E> {
10851085 unsafe { init_from_closure ( |_| Ok ( ( ) ) ) }
10861086}
10871087
1088+ /// Initializes an array by initializing each element via the provided initializer.
1089+ ///
1090+ /// # Examples
1091+ ///
1092+ /// ```rust
1093+ /// # use pinned_init::*;
1094+ /// use pinned_init::init_array_from_fn;
1095+ /// let array: Box<[usize; 1_000]> = Box::init(init_array_from_fn(|i| i)).unwrap();
1096+ /// assert_eq!(array.len(), 1_000);
1097+ /// ```
1098+ pub fn init_array_from_fn < I , const N : usize , T , E > (
1099+ mut make_init : impl FnMut ( usize ) -> I ,
1100+ ) -> impl Init < [ T ; N ] , E >
1101+ where
1102+ I : Init < T , E > ,
1103+ {
1104+ let init = move |slot : * mut [ T ; N ] | {
1105+ let slot = slot. cast :: < T > ( ) ;
1106+ for i in 0 ..N {
1107+ let init = make_init ( i) ;
1108+ // SAFETY: Since 0 <= `i` < N, it is still in bounds of `[T; N]`.
1109+ let ptr = unsafe { slot. add ( i) } ;
1110+ // SAFETY: The pointer is derived from `slot` and thus satisfies the `__init`
1111+ // requirements.
1112+ match unsafe { init. __init ( ptr) } {
1113+ Ok ( ( ) ) => { }
1114+ Err ( e) => {
1115+ // SAFETY: The loop has initialized the elements `slot[0..i]` and since we
1116+ // return `Err` below, `slot` will be considered uninitialized memory.
1117+ unsafe { ptr:: drop_in_place ( ptr:: slice_from_raw_parts_mut ( slot, i) ) } ;
1118+ return Err ( e) ;
1119+ }
1120+ }
1121+ }
1122+ Ok ( ( ) )
1123+ } ;
1124+ // SAFETY: The initializer above initializes every element of the array. On failure it drops
1125+ // any initialized elements and returns `Err`.
1126+ unsafe { init_from_closure ( init) }
1127+ }
1128+
1129+ /// Initializes an array by initializing each element via the provided initializer.
1130+ ///
1131+ /// # Examples
1132+ ///
1133+ /// ```rust
1134+ /// # #![feature(allocator_api)]
1135+ /// # #[path = "../examples/mutex.rs"] mod mutex; use mutex::*;
1136+ /// # use pinned_init::*;
1137+ /// # use core::pin::Pin;
1138+ /// use pinned_init::pin_init_array_from_fn;
1139+ /// use std::sync::Arc;
1140+ /// let array: Pin<Arc<[CMutex<usize>; 1_000]>> =
1141+ /// Arc::pin_init(pin_init_array_from_fn(|i| CMutex::new(i))).unwrap();
1142+ /// assert_eq!(array.len(), 1_000);
1143+ /// ```
1144+ pub fn pin_init_array_from_fn < I , const N : usize , T , E > (
1145+ mut make_init : impl FnMut ( usize ) -> I ,
1146+ ) -> impl PinInit < [ T ; N ] , E >
1147+ where
1148+ I : PinInit < T , E > ,
1149+ {
1150+ let init = move |slot : * mut [ T ; N ] | {
1151+ let slot = slot. cast :: < T > ( ) ;
1152+ for i in 0 ..N {
1153+ let init = make_init ( i) ;
1154+ // SAFETY: Since 0 <= `i` < N, it is still in bounds of `[T; N]`.
1155+ let ptr = unsafe { slot. add ( i) } ;
1156+ // SAFETY: The pointer is derived from `slot` and thus satisfies the `__init`
1157+ // requirements.
1158+ match unsafe { init. __pinned_init ( ptr) } {
1159+ Ok ( ( ) ) => { }
1160+ Err ( e) => {
1161+ // SAFETY: The loop has initialized the elements `slot[0..i]` and since we
1162+ // return `Err` below, `slot` will be considered uninitialized memory.
1163+ unsafe { ptr:: drop_in_place ( ptr:: slice_from_raw_parts_mut ( slot, i) ) } ;
1164+ return Err ( e) ;
1165+ }
1166+ }
1167+ }
1168+ Ok ( ( ) )
1169+ } ;
1170+ // SAFETY: The initializer above initializes every element of the array. On failure it drops
1171+ // any initialized elements and returns `Err`.
1172+ unsafe { pin_init_from_closure ( init) }
1173+ }
1174+
10881175// SAFETY: Every type can be initialized by-value.
10891176unsafe impl < T , E > Init < T , E > for T {
10901177 unsafe fn __init ( self , slot : * mut T ) -> Result < ( ) , E > {
0 commit comments