slice_rc/
uninit.rs

1use std::{fmt::{self, Debug, Formatter, Pointer}, marker::PhantomData, mem::forget, ptr::NonNull};
2
3use crate::{inner::AllocUninit, InnerHeader, Src, SrcSlice, SrcTarget, UniqueSrc, WeakSrc};
4
5/// `UninitSrc` is a version of [`Src`] that uniquely owns a new allocation before its body is initialized.
6/// This is primarily used to construct self-referential data structures:
7/// the [`downgrade`](UninitSrc::downgrade) method allows aquiring [weak references](WeakSrc) to this allocation before its body is initialized.
8/// 
9/// There are several helper methods for [`Src`] and [`UniqueSrc`] such as [`cyclic_from_fn`](Src::cyclic_from_fn) that may be simpler than `UninitSrc` for specific use cases.
10/// 
11/// `UninitSrc` pointers are always [root](crate#root)s,
12/// because there is (at least at present) no way to track which elements are initialized and which are not,
13/// and a non-[root](crate#root) `UninitSrc` would be useless if you couldn't initialize it.
14/// 
15/// Note that there is no way to construct or initialize an <code>UninitSrc\<[str]></code>;
16/// however, as a [`str`] cannot contain a <code>[WeakSrc]\<[str]></code>, this type is useless with [`str`] anyway.
17pub struct UninitSrc<T: SrcTarget + ?Sized> {
18  
19  // SAFETY:
20  // requires:
21  // * initialized from InnerHeader::new_inner::<T::Item>(_)
22  pub(crate) header: NonNull<InnerHeader>,
23  // SAFETY:
24  // requires when T: SrcSlice:
25  // * self.start.add(self.len) <= InnerHeader::get_body_ptr::<T::Item>(self.header).add(InnerHeader::get_header(self.header).len())
26  // requires when T: Sized:
27  // * self.start < InnerHeader::get_body_ptr::<T::Item>(self.header).add(InnerHeader::get_header(self.header).len())
28  pub(crate) len: T::Len,
29  pub(crate) _phantom: PhantomData<*const T>,
30  
31}
32
33impl<T: SrcTarget + ?Sized> UninitSrc<T> {
34  
35  fn header(&self) -> &InnerHeader {
36    // SAFETY:
37    // * all constructor fns for Src initialize header from InnerHeader::new_inner::<T::Item>
38    // * the header is only accessed from InnerHeader::get_header
39    unsafe { InnerHeader::get_header(self.header) }
40  }
41  
42  /// Creates a [root](crate#root) [`WeakSrc`] pointer to this allocation.
43  /// 
44  /// ```rust
45  /// use slice_rc::{Src, UninitSrc, WeakSrc};
46  /// 
47  /// struct S {
48  ///   
49  ///   me: WeakSrc<S>,
50  ///   
51  /// }
52  /// 
53  /// let uninit = UninitSrc::single();
54  /// let s = S { me: uninit.downgrade() };
55  /// let s = uninit.init(s);
56  /// assert!(Src::ptr_eq(&s, &s.me.upgrade().unwrap()));
57  /// ```
58  pub fn downgrade(&self) -> WeakSrc<T> {
59    // safety note: the strong count is 0 until this UninitSrc is initialized into a Src, so the WeakSrc will never read or write from the body during the lifetime of the UninitSrc
60    self.header().inc_weak_count();
61    // SAFETY:
62    // * all constructor fns for UninitSrc<T> initialize self.header from InnerHeader::new_inner::<T>
63    // * the header is only accessed from InnerHeader::get_header
64    let start = unsafe { InnerHeader::get_body_ptr::<T::Item>(self.header) };
65    WeakSrc {
66      // SAFETY: the safety invariant for self.header implies that of _.header
67      header: self.header,
68      // SAFETY: the start we just calculated meets the safety invariant by definition
69      start,
70      // SAFETY: the safety invariant for self.len implies tha tof _.len
71      len: self.len,
72      _phantom: PhantomData,
73    }
74  }
75  
76}
77
78impl<T: SrcSlice + ?Sized> UninitSrc<T> {
79  
80  /// Returns the number of (uninitialized) elements in this `UninitSrc`.
81  /// Because `UninitSrc` pointers are always [root](crate#root),
82  /// this is also the total number of elements in this allocation.
83  /// 
84  /// ```rust
85  /// use slice_rc::UninitSrc;
86  /// 
87  /// let uninit = UninitSrc::<[i32]>::new(3);
88  /// assert_eq!(uninit.len(), 3);
89  /// ```
90  #[inline]
91  pub fn len(&self) -> usize {
92    self.len
93  }
94  
95  /// Returns `true` if this `UninitSrc` has a length of `0`.
96  /// 
97  /// ```rust
98  /// use slice_rc::UninitSrc;
99  /// 
100  /// let a = UninitSrc::<[i32]>::new(3);
101  /// assert!(!a.is_empty());
102  /// 
103  /// let b = UninitSrc::<[i32]>::new(0);
104  /// assert!(b.is_empty());
105  /// ```
106  #[inline]
107  pub fn is_empty(&self) -> bool {
108    self.len == 0
109  }
110  
111}
112
113impl<T: Sized> UninitSrc<T> {
114  
115  /// Constructs a new `UninitSrc` for a single value.
116  /// 
117  /// ```rust
118  /// use slice_rc::{Src, UninitSrc};
119  /// 
120  /// let uninit = UninitSrc::<i32>::single();
121  /// assert_eq!(uninit.as_slice().len(), 1);
122  /// ```
123  #[inline]
124  pub fn single() -> UninitSrc<T> {
125    let this = UninitSrc::<[T]>::new(1);
126    debug_assert_eq!(this.len, 1);
127    let this2 = UninitSrc {
128      // SAFETY: the safety invariant of this.header is the same as this2.header
129      header: this.header,
130      // SAFETY: the safety invariant of this.len is implies that of this2.len
131      len: (),
132      _phantom: PhantomData,
133    };
134    forget(this);
135    this2
136  }
137  
138  /// Initializes this `UninitSrc` into an [`Src`] with the given value.
139  /// 
140  /// ```rust
141  /// use slice_rc::{Src, UninitSrc};
142  /// 
143  /// let uninit = UninitSrc::single();
144  /// let s: Src<_> = uninit.init(42);
145  /// assert_eq!(*s, 42);
146  /// assert_eq!(Src::root(&s).len(), 1);
147  /// ```
148  #[inline]
149  pub fn init(self, value: T) -> Src<T> {
150    UniqueSrc::into_shared(self.init_unique(value))
151  }
152  
153  /// Initializes this `UninitSrc` into a [`UniqueSrc`] with the given value.
154  /// 
155  /// ```rust
156  /// use slice_rc::{UninitSrc, UniqueSrc};
157  /// 
158  /// let uninit = UninitSrc::single();
159  /// let s: UniqueSrc<_> = uninit.init_unique(42);
160  /// assert_eq!(*s, 42);
161  /// ```
162  pub fn init_unique(self, value: T) -> UniqueSrc<T> {
163    // SAFETY:
164    // * all constructor fns for UninitSrc<T> initialize self.header from InnerHeader::new_inner::<T>
165    // * the header is only accessed from InnerHeader::get_header
166    let start = unsafe { InnerHeader::get_body_ptr::<T>(self.header) };
167    // SAFETY: no one else has seen the body of the allocation (because the weaks only look at the header after the strong count has been initialized), so this write is okay
168    unsafe { start.write(value); }
169    let this = UniqueSrc {
170      // SAFETY: the safety invariant of self.header implies that of this.header
171      header: self.header,
172      // SAFETY: after being initialized by start.write(_), the safety invariant of this.start is fulfilled by definition
173      start,
174      // SAFETY: the safety invariant of self.len implies that of this.len
175      len: self.len,
176      _phantom: PhantomData,
177    };
178    forget(self); // don't drop the weak held by the UninitSrc; it logically transfers to the Src
179    this
180  }
181  
182  /// Returns a `UninitSrc` equivalent to this one, but typed as a slice rather than a single element.
183  /// The returned slice will have a length of `1`, and its element `0` will be at the same location in memory as `self`'s value.
184  /// 
185  /// ```rust
186  /// use slice_rc::{UninitSrc, WeakSrc};
187  /// 
188  /// let single = UninitSrc::<i32>::single();
189  /// let single_weak: WeakSrc<i32> = single.downgrade();
190  /// let slice = single.as_slice();
191  /// let slice_weak: WeakSrc<[i32]> = slice.downgrade();
192  /// assert!(WeakSrc::ptr_eq(&single_weak, &slice_weak));
193  /// ```
194  #[inline]
195  pub fn as_slice(self) -> UninitSrc<[T]> {
196    let this = UninitSrc {
197      // SAFETY: the safety invariant of self.header is the same as this.header
198      header: self.header,
199      // SAFETY: the safety invariant of self.len implies that of this.len
200      len: 1,
201      _phantom: PhantomData,
202    };
203    forget(self); // don't modify the weak count because this is logically the same UninitSrc
204    this
205  }
206  
207}
208
209impl<T> UninitSrc<[T]> {
210  
211  /// Constructs a new `UninitSrc` for a slice of `len` values.
212  /// 
213  /// ```rust
214  /// use slice_rc::UninitSrc;
215  /// 
216  /// let uninit = UninitSrc::<[i32]>::new(3);
217  /// assert_eq!(uninit.len(), 3);
218  /// ```
219  #[inline]
220  pub fn new(len: usize) -> UninitSrc<[T]> {
221    let header = InnerHeader::new_inner::<T, AllocUninit>(len);
222    Self {
223      // SAFETY: the safety invariant of _.header is fulfilled by definition
224      header,
225      // SAFETY: the safety invariant of _.len is fulfilled by definition
226      len,
227      _phantom: PhantomData,
228    }
229  }
230  
231  /// Initializes this `UninitSrc` into an [`Src`] where each element is produced by calling `f` with that element's index while walking forward through the slice.
232  /// 
233  /// If `len == 0`, this produces an empty [`Src`] without ever calling `f`.
234  /// 
235  /// ```rust
236  /// use slice_rc::UninitSrc;
237  /// 
238  /// let uninit = UninitSrc::new(5);
239  /// let slice = uninit.init_from_fn(|i| i);
240  /// assert_eq!(*slice, [0, 1, 2, 3, 4]);
241  /// 
242  /// let uninit2 = UninitSrc::new(8);
243  /// let slice2 = uninit2.init_from_fn(|i| i * 2);
244  /// assert_eq!(*slice2, [0, 2, 4, 6, 8, 10, 12, 14]);
245  /// 
246  /// let bool_uninit = UninitSrc::new(5);
247  /// let bool_slice = bool_uninit.init_from_fn(|i| i % 2 == 0);
248  /// assert_eq!(*bool_slice, [true, false, true, false, true]);
249  /// ```
250  /// 
251  /// You can also capture things, so you can use closures with mutable state.
252  /// The slice is generated in ascending index order, starting from the front and going towards the back.
253  /// ```rust
254  /// # use slice_rc::UninitSrc;
255  /// let uninit = UninitSrc::new(6);
256  /// let mut state = 1;
257  /// let s = uninit.init_from_fn(|_| { let x = state; state *= 2; x });
258  /// assert_eq!(*s, [1, 2, 4, 8, 16, 32]);
259  /// ```
260  /// 
261  /// # Panics
262  /// 
263  /// Panics if `f` panics; in this event, any elements that have been initialized will be properly dropped.
264  /// ```rust
265  /// # use slice_rc::UninitSrc;
266  /// # use std::cell::Cell;
267  /// thread_local! {
268  ///   static DROPPED: Cell<usize> = Cell::new(0);
269  /// }
270  /// 
271  /// struct Droppable;
272  /// 
273  /// impl Drop for Droppable {
274  ///   fn drop(&mut self) {
275  ///     DROPPED.with(|dropped| dropped.update(|x| x + 1));
276  ///   }
277  /// }
278  /// 
279  /// let _ = std::panic::catch_unwind(move || {
280  ///   let uninit = UninitSrc::new(10);
281  ///   uninit.init_from_fn(|i| {
282  ///     if i >= 5 { panic!() }
283  ///     Droppable
284  ///   })
285  /// });
286  /// 
287  /// assert_eq!(DROPPED.get(), 5);
288  /// ```
289  #[inline]
290  pub fn init_from_fn<F: FnMut(usize) -> T>(self, f: F) -> Src<[T]> {
291    UniqueSrc::into_shared(self.init_unique_from_fn(f))
292  }
293  
294  /// Initializes this `UninitSrc` into a [`UniqueSrc`] where each element is produced by calling `f` with that element's index while walking forward through the slice.
295  /// 
296  /// If `len == 0`, this produces an empty [`UniqueSrc`] without ever calling `f`.
297  /// 
298  /// ```rust
299  /// use slice_rc::UninitSrc;
300  /// 
301  /// let uninit = UninitSrc::new(5);
302  /// let slice = uninit.init_unique_from_fn(|i| i);
303  /// assert_eq!(*slice, [0, 1, 2, 3, 4]);
304  /// 
305  /// let uninit2 = UninitSrc::new(8);
306  /// let slice2 = uninit2.init_unique_from_fn(|i| i * 2);
307  /// assert_eq!(*slice2, [0, 2, 4, 6, 8, 10, 12, 14]);
308  /// 
309  /// let bool_uninit = UninitSrc::new(5);
310  /// let bool_slice = bool_uninit.init_unique_from_fn(|i| i % 2 == 0);
311  /// assert_eq!(*bool_slice, [true, false, true, false, true]);
312  /// ```
313  /// 
314  /// You can also capture things, so you can use closures with mutable state.
315  /// The slice is generated in ascending index order, starting from the front and going towards the back.
316  /// ```rust
317  /// # use slice_rc::UninitSrc;
318  /// let uninit = UninitSrc::new(6);
319  /// let mut state = 1;
320  /// let s = uninit.init_unique_from_fn(|_| { let x = state; state *= 2; x });
321  /// assert_eq!(*s, [1, 2, 4, 8, 16, 32]);
322  /// ```
323  /// 
324  /// # Panics
325  /// 
326  /// Panics if `f` panics; in this event, any elements that have been initialized will be properly dropped.
327  /// ```rust
328  /// # use slice_rc::UninitSrc;
329  /// # use std::cell::Cell;
330  /// thread_local! {
331  ///   static DROPPED: Cell<usize> = Cell::new(0);
332  /// }
333  /// 
334  /// struct Droppable;
335  /// 
336  /// impl Drop for Droppable {
337  ///   fn drop(&mut self) {
338  ///     DROPPED.with(|dropped| dropped.update(|x| x + 1));
339  ///   }
340  /// }
341  /// 
342  /// let _ = std::panic::catch_unwind(move || {
343  ///   let uninit = UninitSrc::new(10);
344  ///   uninit.init_unique_from_fn(|i| {
345  ///     if i >= 5 { panic!() }
346  ///     Droppable
347  ///   })
348  /// });
349  /// 
350  /// assert_eq!(DROPPED.get(), 5);
351  /// ```
352  pub fn init_unique_from_fn<F: FnMut(usize) -> T>(self, mut f: F) -> UniqueSrc<[T]> {
353    let header = self.header();
354    // SAFETY:
355    // * all constructor fns for UninitSrc<T> initialize self.header from InnerHeader::new_inner::<T>
356    // * the header is only accessed from InnerHeader::get_header
357    let start = unsafe { InnerHeader::get_body_ptr::<T>(self.header) };
358    let mut guard = PartialInitGuard::<T> { header: self.header, initialized: 0, _phantom: PhantomData };
359    for i in 0..header.len() {
360      // SAFETY:
361      // * all constructor fns for UninitSrc<T> initialize self.header from InnerHeader::new_inner::<T>
362      // * the header is only accessed from InnerHeader::get_header
363      let ptr = unsafe { InnerHeader::get_elem_ptr::<T>(self.header, i) };
364      let val = f(i);
365      // SAFETY: no one else has seen the body of the allocation (because the weaks only look at the header after the strong count has been initialized), so this write is okay
366      unsafe { ptr.write(val) };
367      guard.initialized += 1;
368    }
369    // if all elements are successfully initialized, then forget the drop guard; in other words, the guard only drops the contents if a panic occurs part way through initialization
370    forget(guard);
371    let this = UniqueSrc {
372      // SAFETY: the safety invariant of self.header is the same as this.header
373      header: self.header,
374      // SAFETY: after a successful initialization, the safety invariant of this.start is fulfilled by definition
375      start,
376      // SAFETY: the safety invariant of self.len is the same as this.len
377      len: self.len,
378      _phantom: PhantomData,
379    };
380    forget(self); // don't drop the weak held by the UninitSrc; it logically transfers to the Src
381    this
382  }
383  
384  /// Initializes this `UninitSrc` into an [`Src`] where each element is the type's [default](Default::default).
385  /// 
386  /// This method is essentially equivalent to <code>self.[init_from_fn](UninitSrc::init_from_fn)(|_| [Default::default]\())</code>.
387  #[inline]
388  pub fn init_from_default(self) -> Src<[T]> where T: Default {
389    self.init_from_fn(|_| T::default())
390  }
391  
392  /// Initializes this `UninitSrc` into a [`UniqueSrc`] where each element is the type's [default](Default::default).
393  /// 
394  /// This method is essentially equivalent to <code>self.[init_unique_from_fn](UninitSrc::init_unique_from_fn)(|_| [Default::default]\())</code>.
395  #[inline]
396  pub fn init_unique_from_default(self) -> UniqueSrc<[T]> where T: Default {
397    self.init_unique_from_fn(|_| T::default())
398  }
399  
400  /// Initializes this `UninitSrc` into an [`Src`] where each element is a clone of `value`.
401  /// 
402  /// This method is essentially equivalent to <code>self.[init_from_fn](UninitSrc::init_from_fn)(|_| value.[Clone::clone]\())</code>.
403  #[inline]
404  pub fn init_filled(self, value: &T) -> Src<[T]> where T: Clone {
405    self.init_from_fn(|_| value.clone())
406  }
407  
408  /// Initializes this `UninitSrc` into an [`UniqueSrc`] where each element is a clone of `value`.
409  /// 
410  /// This method is essentially equivalent to <code>self.[init_unique_from_fn](UninitSrc::init_unique_from_fn)(|_| value.[Clone::clone]\())</code>.
411  #[inline]
412  pub fn init_unique_filled(self, value: &T) -> UniqueSrc<[T]> where T: Clone {
413    self.init_unique_from_fn(|_| value.clone())
414  }
415  
416}
417
418impl<T: SrcTarget + ?Sized> Debug for UninitSrc<T> {
419  
420  #[inline]
421  fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
422    write!(f, "(UninitSrc)")
423  }
424  
425}
426
427impl<T: SrcTarget + ?Sized> Pointer for UninitSrc<T> {
428  
429  #[inline]
430  fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
431    // SAFETY:
432    // * all constructor fns for Src initialize header from InnerHeader::new_inner::<T::Item>
433    // * the header is only accessed from InnerHeader::get_header
434    // NOTE: the body is not expected to be initialized, but it is also not used
435    let start = unsafe { InnerHeader::get_body_ptr::<T::Item>(self.header) };
436    Pointer::fmt(&start, f)
437  }
438  
439}
440
441impl<T: SrcTarget + ?Sized> Drop for UninitSrc<T> {
442  
443  fn drop(&mut self) {
444    // SAFETY:
445    // * all constructor fns for UninitSrc initialize header from InnerHeader::new_inner::<T::Item>
446    // * the header is only accessed from InnerHeader::get_header
447    // NOTE: the UninitSrc logically holds one weak reference
448    unsafe { InnerHeader::drop_weak::<T::Item>(self.header); }
449  }
450  
451}
452
453struct PartialInitGuard<T> {
454  
455  header: NonNull<InnerHeader>,
456  initialized: usize,
457  _phantom: PhantomData<*const T>,
458  
459}
460
461impl<T> Drop for PartialInitGuard<T> {
462  
463  fn drop(&mut self) {
464    // SAFETY:
465    // * by the contract of this type, self.header is from an initialization fn from UninitSrc; all constructor fns for UninitSrc<T> initialize self.header from InnerHeader::new_inner::<T>
466    // * by the contract of this type, the first self.initialized elements have been initialized
467    // * the header is only accessed from InnerHeader::get_header
468    // * by the contract of this type, self.header is from an initialization fn from UninitSrc that is panicking; therefore, no one else has seen or will see the body
469    unsafe { InnerHeader::drop_body_up_to::<T>(self.header, self.initialized); }
470  }
471  
472}
473
474#[cfg(test)]
475mod tests {
476  
477  use std::{cell::Cell, ops::Deref, panic::{catch_unwind, AssertUnwindSafe}};
478  use crate::*;
479  
480  #[test]
481  fn downgrade() {
482    let u: UninitSrc<[u8]> = UninitSrc::new(3);
483    let w: WeakSrc<[u8]> = u.downgrade();
484    assert!(w.upgrade().is_none());
485    let s1: Src<[u8]> = u.init_from_default();
486    let s2: Src<[u8]> = w.upgrade().unwrap();
487    assert_eq!(s1, s2);
488    assert!(Src::ptr_eq(&s1, &s2));
489  }
490  
491  #[test]
492  fn len() {
493    let u: UninitSrc<[u8]> = UninitSrc::new(0);
494    assert_eq!(u.len(), 0);
495    let u: UninitSrc<[u8]> = UninitSrc::new(1);
496    assert_eq!(u.len(), 1);
497    let u: UninitSrc<[u8]> = UninitSrc::new(17);
498    assert_eq!(u.len(), 17);
499  }
500  
501  #[test]
502  fn is_empty() {
503    let u: UninitSrc<[u8]> = UninitSrc::new(0);
504    assert!(u.is_empty());
505    let u: UninitSrc<[u8]> = UninitSrc::new(1);
506    assert!(!u.is_empty());
507    let u: UninitSrc<[u8]> = UninitSrc::new(17);
508    assert!(!u.is_empty());
509  }
510  
511  #[test]
512  fn single() {
513    let u: UninitSrc<u8> = UninitSrc::single();
514    let s: Src<u8> = u.init(42);
515    assert!(Src::is_root(&s));
516    let s: Src<[u8]> = Src::as_slice(&s);
517    assert_eq!(s.len(), 1);
518  }
519  
520  #[test]
521  fn init() {
522    let u: UninitSrc<u8> = UninitSrc::single();
523    let s: Src<u8> = u.init(42);
524    assert_eq!(*s, 42);
525  }
526  
527  #[test]
528  fn init_unique() {
529    let u: UninitSrc<u8> = UninitSrc::single();
530    let u: UniqueSrc<u8> = u.init_unique(42);
531    assert_eq!(*u, 42);
532  }
533  
534  #[test]
535  fn as_slice() {
536    let u: UninitSrc<u8> = UninitSrc::single();
537    let u: UninitSrc<[u8]> = u.as_slice();
538    assert_eq!(u.len(), 1);
539  }
540  
541  #[test]
542  fn new() {
543    let u: UninitSrc<[u8]> = UninitSrc::new(3);
544    let s: Src<[u8]> = u.init_from_fn(|i| i as _);
545    assert!(Src::is_root(&s));
546    assert_eq!(s.len(), 3);
547  }
548  
549  #[test]
550  fn init_from_fn() {
551    { // normal
552      let u: UninitSrc<[u8]> = UninitSrc::new(3);
553      let s: Src<[u8]> = u.init_from_fn(|i| i as _);
554      assert_eq!(*s, [0, 1, 2]);
555    }
556    { // panic
557      let drop_flags: [_; 6] = std::array::from_fn(|_| AssertUnwindSafe(Cell::new(false)));
558      struct DropFlagger<'a>(&'a Cell<bool>);
559      impl Drop for DropFlagger<'_> {
560        
561        fn drop(&mut self) {
562          self.0.update(|v| !v)
563        }
564        
565      }
566      let _: Result<_, _> = catch_unwind(|| {
567        let u: UninitSrc<[DropFlagger<'_>]> = UninitSrc::new(drop_flags.len());
568        let _: Src<[DropFlagger<'_>]> = u.init_from_fn(|i| {
569          if i >= 3 { panic!() }
570          DropFlagger(&drop_flags[i])
571        });
572      });
573      assert!(drop_flags[..3].iter().map(Deref::deref).all(Cell::get));
574      assert!(!drop_flags[3..].iter().map(Deref::deref).any(Cell::get));
575    }
576  }
577  
578  #[test]
579  fn init_unique_from_fn() {
580    { // normal
581      let u: UninitSrc<[u8]> = UninitSrc::new(3);
582      let u: UniqueSrc<[u8]> = u.init_unique_from_fn(|i| i as _);
583      assert_eq!(*u, [0, 1, 2]);
584    }
585    { // panic
586      let drop_flags: [_; 6] = std::array::from_fn(|_| AssertUnwindSafe(Cell::new(false)));
587      struct DropFlagger<'a>(&'a Cell<bool>);
588      impl Drop for DropFlagger<'_> {
589        
590        fn drop(&mut self) {
591          self.0.update(|v| !v)
592        }
593        
594      }
595      let _: Result<_, _> = catch_unwind(|| {
596        let u: UninitSrc<[DropFlagger<'_>]> = UninitSrc::new(drop_flags.len());
597        let _: UniqueSrc<[DropFlagger<'_>]> = u.init_unique_from_fn(|i| {
598          if i >= 3 { panic!() }
599          DropFlagger(&drop_flags[i])
600        });
601      });
602      assert!(drop_flags[..3].iter().map(Deref::deref).all(Cell::get));
603      assert!(!drop_flags[3..].iter().map(Deref::deref).any(Cell::get));
604    }
605  }
606  
607  #[test]
608  fn init_from_default() {
609    let u: UninitSrc<[u8]> = UninitSrc::new(3);
610    let s: Src<[u8]> = u.init_from_default();
611    assert_eq!(*s, [0, 0, 0]);
612  }
613  
614  #[test]
615  fn init_unique_from_default() {
616    let u: UninitSrc<[u8]> = UninitSrc::new(3);
617    let u: UniqueSrc<[u8]> = u.init_unique_from_default();
618    assert_eq!(*u, [0, 0, 0]);
619  }
620  
621  #[test]
622  fn init_filled() {
623    let u: UninitSrc<[u8]> = UninitSrc::new(3);
624    let s: Src<[u8]> = u.init_filled(&42);
625    assert_eq!(*s, [42, 42, 42]);
626  }
627  
628  #[test]
629  fn init_unique_filled() {
630    let u: UninitSrc<[u8]> = UninitSrc::new(3);
631    let u: UniqueSrc<[u8]> = u.init_unique_filled(&42);
632    assert_eq!(*u, [42, 42, 42]);
633  }
634  
635  #[test]
636  fn drop() {
637    let u: UninitSrc<[u8]> = UninitSrc::new(3);
638    let w: WeakSrc<[u8]> = u.downgrade();
639    assert!(w.upgrade().is_none());
640    std::mem::drop(u);
641    assert!(w.upgrade().is_none());
642  }
643  
644}