MCPcopy Index your code
hub / github.com/Manishearth/array-init / try_array_init_impl

Function try_array_init_impl

src/lib.rs:193–315  ·  view source on GitHub ↗
(
    mut initializer: F,
)

Source from the content-addressed store, hash-verified

191
192#[inline]
193fn try_array_init_impl<Err, F, T, const N: usize, const D: i8>(
194 mut initializer: F,
195) -> Result<[T; N], Err>
196where
197 F: FnMut(usize) -> Result<T, Err>,
198{
199 // The implementation differentiates two cases:
200 // A) `T` does not need to be dropped. Even if the initializer panics
201 // or returns `Err` we will not leak memory.
202 // B) `T` needs to be dropped. We must keep track of which elements have
203 // been initialized so far, and drop them if we encounter a panic or `Err` midway.
204 if !mem::needs_drop::<T>() {
205 let mut array: MaybeUninit<[T; N]> = MaybeUninit::uninit();
206 // pointer to array = *mut [T; N] <-> *mut T = pointer to first element
207 let mut ptr_i = array.as_mut_ptr() as *mut T;
208
209 // # Safety
210 //
211 // - for D > 0, we are within the array since we start from the
212 // beginning of the array, and we have `0 <= i < N`.
213 // - for D < 0, we start at the end of the array and go back one
214 // place before writing, going back N times in total, finishing
215 // at the start of the array.
216 unsafe {
217 if D < 0 {
218 ptr_i = ptr_i.add(N);
219 }
220 for i in 0..N {
221 let value_i = initializer(i)?;
222 // We overwrite *ptr_i previously undefined value without reading or dropping it.
223 if D < 0 {
224 ptr_i = ptr_i.sub(1);
225 }
226 ptr_i.write(value_i);
227 if D > 0 {
228 ptr_i = ptr_i.add(1);
229 }
230 }
231 Ok(array.assume_init())
232 }
233 } else {
234 // else: `mem::needs_drop::<T>()`
235
236 /// # Safety
237 ///
238 /// - `base_ptr[.. initialized_count]` must be a slice of init elements...
239 ///
240 /// - ... that must be sound to `ptr::drop_in_place` if/when
241 /// `UnsafeDropSliceGuard` is dropped: "symbolic ownership"
242 struct UnsafeDropSliceGuard<Item> {
243 base_ptr: *mut Item,
244 initialized_count: usize,
245 }
246
247 impl<Item> Drop for UnsafeDropSliceGuard<Item> {
248 fn drop(self: &'_ mut Self) {
249 unsafe {
250 // # Safety

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected