slice_rc/unique.rs
1use std::{borrow::{Borrow, BorrowMut}, cmp::Ordering, fmt::{self, Debug, Formatter, Pointer}, hash::{Hash, Hasher}, marker::PhantomData, mem::{forget, MaybeUninit}, ops::{Deref, DerefMut, Index, IndexMut}, ptr::NonNull, str::Utf8Error};
2
3use crate::{inner::{AllocUninit, AllocZeroed}, InnerHeader, Src, SrcSlice, SrcTarget, UninitSrc, WeakSrc};
4
5/// A uniquely owned [`Src`].
6///
7/// This represents an [`Src`] that is known to be uniquely owned - that is, have exactly one strong reference.
8/// Multiple [weak pointers](WeakSrc) can be created, but attempts to upgrade those to strong references will fail unless the `UniqueSrc` has been converted to a regular shared [`Src`].
9///
10/// Because they are uniquely owned, the contents of a `UniqueSrc` can be freely mutated.
11/// This could be used as an initialization step (that is the suggested usage of [`UniqueRc`](std::rc::UniqueRc)),
12/// but I find [`UninitSrc`] to be better for initialization, as there is no intermediate step with [dangling](WeakSrc#dangling) weak pointers.
13///
14/// Still, the ability to mutably access the contents of an [`Src`] can be useful, hence this type's inclusion in the crate.
15/// (Also, [`Src::into_unique`] and [`Src::make_unique`] are currently this crate's substitutes for [`Rc::get_mut`](std::rc::Rc::get_mut) and [`Rc::make_mut`](std::rc::Rc::make_mut) respectively;
16/// since I made that decision, I have since realized that they are not equivalent, and will therefore probably add `get_mut` and `make_mut` methods to [`Src`] at some point.
17/// In the mean time, this is the next best thing.)
18///
19/// Note that, while this struct currently has no methods to explicitly support non-[root](crate#root) `UniqueSrc`s,
20/// it is technically possible to construct them by making a non-[root](crate#root) [`Src`] and turning into a `UniqueSrc` via [`Src::into_unique`] or [`Src::make_unique`];
21/// The behavior of these non-[root](crate#root) `UniqueSrc`s has not been thoroughly considered and may be changed or removed.
22///
23/// Many of the inherent methods of `UniqueSrc` are associated functions, which means that you have to call them as e.g.,
24/// [`UniqueSrc::downgrade(&value)`](UniqueSrc::downgrade) instead of `value.downgrade()`;
25/// this avoids conflicts with methods of the inner type `T`.
26/// However, some methods, e.g. [`Src::len`], intentionally shadow a known method of the inner type because they use a more efficient computation for the same result,
27/// and there may be some in the future (e.g. the hypothetical `UniqueSrc::slice`), which will be permitted to remain as methods because their inner type will be known not to have a conflicting method.
28pub struct UniqueSrc<T: SrcTarget + ?Sized> {
29
30 // SAFETY:
31 // requires:
32 // * initialized from InnerHeader::new_inner::<T::Item>(_)
33 pub(crate) header: NonNull<InnerHeader>,
34 // SAFETY:
35 // requires:
36 // * initialized from either InnerHeader::get_body_ptr::<T::Item>(self.header) or InnerHeader::get_elem_ptr::<T::Item>(self.header, i) where 0 <= i <= InnerHeader::get_header(self.header).len()
37 // * all body elements have been properly initialized (e.g., self.start.as_ref() will not cause UB)
38 pub(crate) start: NonNull<T::Item>,
39 // SAFETY:
40 // requires when T: SrcSlice:
41 // * self.start.add(self.len) <= InnerHeader::get_body_ptr::<T::Item>(self.header).add(InnerHeader::get_header(self.header).len())
42 // requires when T: Sized:
43 // * self.start < InnerHeader::get_body_ptr::<T::Item>(self.header).add(InnerHeader::get_header(self.header).len())
44 pub(crate) len: T::Len,
45 pub(crate) _phantom: PhantomData<*const T>,
46
47}
48
49impl<T: SrcTarget + ?Sized> UniqueSrc<T> {
50
51 fn header(&self) -> &InnerHeader {
52 // SAFETY:
53 // * all constructor fns for Src initialize header from InnerHeader::new_inner::<T::Item>
54 // * the header is only accessed from InnerHeader::get_header
55 unsafe { InnerHeader::get_header(self.header) }
56 }
57
58 /// Creates a [`WeakSrc`] pointer to this slice.
59 /// The [`WeakSrc`] refers to the same slice as this `UniqueSrc`, and therefore, refers to the [root](crate#root) if and only if this `UniqueSrc` does.
60 ///
61 /// ```rust
62 /// use slice_rc::UniqueSrc;
63 ///
64 /// let root = UniqueSrc::from_array([1, 2, 3]);
65 ///
66 /// let weak_root = UniqueSrc::downgrade(&root);
67 /// ```
68 pub fn downgrade(this: &UniqueSrc<T>) -> WeakSrc<T> {
69 // safety note: the strong count is 0 until this UniqueSrc is turned into a Src, so the WeakSrc will never read or write from the body during the lifetime of the UniqueSrc
70 this.header().inc_weak_count();
71 WeakSrc {
72 // SAFETY: the safety invariant of this.header implies that of _.header
73 header: this.header,
74 // SAFETY: the safety invariant of this.start implies that of _.start
75 start: this.start,
76 // SAFETY: the safety invariant of this.len implies that of _.len
77 len: this.len,
78 _phantom: PhantomData,
79 }
80 }
81
82 /// Turns this `UniqueSrc` into an [`Src`].
83 /// Because `UniqueSrc` has strictly stronger guarantees, this conversion is not fallible.
84 ///
85 /// ```rust
86 /// use slice_rc::UniqueSrc;
87 ///
88 /// let x = UniqueSrc::single(3);
89 /// assert_eq!(*UniqueSrc::into_shared(x), 3);
90 /// ```
91 ///
92 /// See also [`Src::into_unique`] and [`Src::make_unique`].
93 pub fn into_shared(this: UniqueSrc<T>) -> Src<T> {
94 this.header().inc_strong_count();
95 let this2 = Src {
96 // SAFETY: the safety invariant of this.header is the same as this2.header
97 header: this.header,
98 // SAFETY: the safety invariant of this.start is the same as this2.start
99 start: this.start,
100 // SAFETY: the safety invariant of this.len is the same as this2.len
101 len: this.len,
102 _phantom: PhantomData,
103 };
104 forget(this);
105 this2
106 }
107
108}
109
110impl<T: SrcSlice + ?Sized> UniqueSrc<T> {
111
112 /// Constructs a new [root](crate#root) `UniqueSrc` of length `0`.
113 /// Note that, because `UniqueSrc`s are not growable like [`Vec`]s are, this allocation will never become larger.
114 /// Every reference to this allocation is a [root](crate#root).
115 ///
116 /// ```rust
117 /// use slice_rc::UniqueSrc;
118 ///
119 /// let s = UniqueSrc::<[i32]>::empty();
120 ///
121 /// assert_eq!(s.len(), 0);
122 /// ```
123 #[inline]
124 pub fn empty() -> UniqueSrc<T> {
125 let this = UniqueSrc::<[T::Item]>::from_array([]);
126 debug_assert_eq!(this.len, 0);
127 let this2 = UniqueSrc {
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.start is the same as this2.start
131 start: this.start,
132 // SAFETY: the safety invariant of this.len implies that of this.len
133 len: this.len,
134 _phantom: PhantomData,
135 };
136 forget(this);
137 this2
138 }
139
140 /// Returns the number of elements in this `UniqueSrc`.
141 /// This method deliberately shadows [`<[T]>::len`](slice::len) and [`str::len`] because this method provides a (slightly) simpler and more efficient implementation.
142 ///
143 /// This method only returns the length of the whole allocation if `self` is a [root](crate#root) `UniqueSrc`.
144 ///
145 /// ```rust
146 /// use slice_rc::UniqueSrc;
147 ///
148 /// let s = UniqueSrc::from_array([1, 2, 3]);
149 /// assert_eq!(s.len(), 3);
150 /// ```
151 #[inline]
152 pub fn len(&self) -> usize {
153 self.len
154 }
155
156 /// Returns `true` if this `UniqueSrc` has a length of `0`.
157 /// This method deliberately shadows [`<[T]>::is_empty`](slice::is_empty) and [`str::is_empty`] because this method provides a (slightly) simpler and more efficient implementation.
158 ///
159 /// Note that this method does not imply that this `UniqueSrc` was constructed via [`UniqueSrc::empty`].
160 /// Similarly, it does not imply that the entire allocation is empty, unless `self` is a [root](crate#root) `UniqueSrc`.
161 ///
162 /// ```rust
163 /// use slice_rc::UniqueSrc;
164 ///
165 /// let a = UniqueSrc::from_array([1, 2, 3]);
166 /// assert!(!a.is_empty());
167 ///
168 /// let b = UniqueSrc::<[i32]>::from_array([]);
169 /// assert!(b.is_empty());
170 /// ```
171 #[inline]
172 pub fn is_empty(&self) -> bool {
173 self.len == 0
174 }
175
176}
177
178impl<T: Sized> UniqueSrc<T> {
179
180 /// Constructs a new [root](crate#root) `UniqueSrc` that contains only the given value.
181 ///
182 /// ```rust
183 /// use slice_rc::UniqueSrc;
184 ///
185 /// let s = UniqueSrc::single(42);
186 /// assert_eq!(*s, 42);
187 /// ```
188 #[inline]
189 pub fn single(value: T) -> UniqueSrc<T> {
190 UninitSrc::single().init_unique(value)
191 }
192
193 /// Constructs a new [root](crate#root) `UniqueSrc` that contains only the value returned from the given function `f`.
194 /// The [`WeakSrc`] that `f` is given will be a weak reference to this allocation, which allows constructing a self-referential value;
195 /// it will return [`None`] from [`WeakSrc::upgrade`] until after `single_cyclic` has returned.
196 ///
197 /// This is a convienience method for a specific subset of behavior that can be obtained via [`UninitSrc`].
198 ///
199 /// ```rust
200 /// use slice_rc::{Src, UniqueSrc, WeakSrc};
201 ///
202 /// struct S {
203 /// me: WeakSrc<S>,
204 /// }
205 ///
206 /// let s = UniqueSrc::single_cyclic(|me| S { me: me.clone() });
207 ///
208 /// assert!(s.me.upgrade().is_none());
209 ///
210 /// let s = UniqueSrc::into_shared(s);
211 ///
212 /// assert!(Src::ptr_eq(&s, &s.me.upgrade().unwrap()));
213 /// ```
214 pub fn single_cyclic<F: FnOnce(&WeakSrc<T>) -> T>(f: F) -> UniqueSrc<T> {
215 let this = UninitSrc::single();
216 let weak = this.downgrade();
217 this.init_unique(f(&weak))
218 }
219
220 /// Constructs a new [root](crate#root) `UniqueSrc` of length `1` with uninitialized contents.
221 ///
222 /// ```rust
223 /// use slice_rc::{UniqueSrc};
224 ///
225 /// let mut five = UniqueSrc::<i32>::single_uninit();
226 ///
227 /// five.write(5);
228 ///
229 /// let five = unsafe { five.assume_init() };
230 ///
231 /// assert_eq!(*five, 5);
232 /// ```
233 #[inline]
234 pub fn single_uninit() -> UniqueSrc<MaybeUninit<T>> {
235 let this = UniqueSrc::<[T]>::new_uninit(1);
236 debug_assert_eq!(this.len, 1);
237 let this2 = UniqueSrc {
238 // SAFETY: the safety invariant of this.header is the same as this2.header
239 header: this.header,
240 // SAFETY: the safety invariant of this.start is the same as this2.start
241 start: this.start,
242 // SAFETY: the safety invariant of this.len implies that of this.len
243 len: (),
244 _phantom: PhantomData,
245 };
246 forget(this);
247 this2
248 }
249
250 /// Constructs a new [root](crate#root) `UniqueSrc` of length `1` with uninitialized contents, with the memory being filled with `0` bytes.
251 ///
252 /// See [`MaybeUninit::zeroed`] for examples of correct and incorrect usage of this method.
253 ///
254 /// ```rust
255 /// use slice_rc::UniqueSrc;
256 ///
257 /// let zero = UniqueSrc::<i32>::single_zeroed();
258 /// let zero = unsafe { zero.assume_init() };
259 ///
260 /// assert_eq!(*zero, 0);
261 /// ```
262 #[inline]
263 pub fn single_zeroed() -> UniqueSrc<MaybeUninit<T>> {
264 let this = UniqueSrc::<[T]>::new_zeroed(1);
265 debug_assert_eq!(this.len, 1);
266 let this2 = UniqueSrc {
267 // SAFETY: the safety invariant of this.header is the same as this2.header
268 header: this.header,
269 // SAFETY: the safety invariant of this.start is the same as this2.start
270 start: this.start,
271 // SAFETY: the safety invariant of this.len implies that of this2.len
272 len: (),
273 _phantom: PhantomData,
274 };
275 forget(this);
276 this2
277 }
278
279 /// Returns a `UniqueSrc` equivalent to this one, but typed as a slice rather than a single element.
280 /// 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.
281 ///
282 /// ```rust
283 /// use slice_rc::{Src, UniqueSrc};
284 /// use std::ptr;
285 ///
286 /// let single = UniqueSrc::single(42);
287 /// let single_weak = UniqueSrc::downgrade(&single);
288 /// let slice = UniqueSrc::as_slice(single);
289 /// let slice = UniqueSrc::into_shared(slice);
290 /// let single = single_weak.upgrade().unwrap();
291 ///
292 /// assert!(Src::ptr_eq(&single, &slice));
293 /// assert!(ptr::eq(&*single, &slice[0]));
294 /// ```
295 #[inline]
296 pub fn as_slice(this: UniqueSrc<T>) -> UniqueSrc<[T]> {
297 let this2 = UniqueSrc {
298 // SAFETY: the safety invariant of this.header is the same as this2.header
299 header: this.header,
300 // SAFETY: the safety invariant of this.start is the same as this2.start
301 start: this.start,
302 // SAFETY: the safety invariant of this.len implies this2.len
303 len: 1,
304 _phantom: PhantomData,
305 };
306 forget(this);
307 this2
308 }
309
310}
311
312impl<T> UniqueSrc<[T]> {
313
314 /// Constructs a new [root](crate#root) `UniqueSrc` of the given length with uninitialized contents.
315 ///
316 /// ```rust
317 /// use slice_rc::{Src, UniqueSrc};
318 ///
319 /// let mut fives = UniqueSrc::<[i32]>::new_uninit(3);
320 ///
321 /// fives[0].write(5);
322 /// fives[1].write(5);
323 /// fives[2].write(5);
324 ///
325 /// let fives = unsafe { fives.assume_init() };
326 ///
327 /// assert_eq!(*fives, [5, 5, 5]);
328 /// ```
329 pub fn new_uninit(len: usize) -> UniqueSrc<[MaybeUninit<T>]> {
330 let header = InnerHeader::new_inner::<T, AllocUninit>(len);
331 // SAFETY:
332 // * we just got this from InnerHeader::new_inner::<T>
333 // * no one else has seen the ptr yet, so the read/write requirements are fine
334 let start = unsafe { InnerHeader::get_body_ptr::<T>(header) }.cast();
335 UniqueSrc {
336 // the safety invariant of _.header is fulfilled by definition
337 header,
338 // the safety invariant of _.start is fulfilled by definition
339 start,
340 // the safety invariant of _.len is fulfilled by definition
341 len,
342 _phantom: PhantomData,
343 }
344 }
345
346 /// Constructs a new [root](crate#root) `UniqueSrc` of the given length with uninitialized contents, with the memory being filled with `0` bytes.
347 ///
348 /// See [`MaybeUninit::zeroed`] for examples of correct and incorrect usage of this method.
349 ///
350 /// ```rust
351 /// use slice_rc::UniqueSrc;
352 ///
353 /// let zeroes = UniqueSrc::<[i32]>::new_zeroed(3);
354 /// let zeroes = unsafe { zeroes.assume_init() };
355 ///
356 /// assert_eq!(*zeroes, [0, 0, 0]);
357 /// ```
358 pub fn new_zeroed(len: usize) -> UniqueSrc<[MaybeUninit<T>]> {
359 let header = InnerHeader::new_inner::<T, AllocZeroed>(len);
360 // SAFETY:
361 // * we just got this from InnerHeader::new_inner::<T>
362 // * no one else has seen the ptr yet, so the read/write requirements are fine
363 let start = unsafe { InnerHeader::get_body_ptr::<T>(header) }.cast();
364 UniqueSrc {
365 // the safety invariant of _.header is fulfilled by definition
366 header,
367 // the safety invariant of _.start is fulfilled by definition
368 start,
369 // the safety invariant of _.len is fulfilled by definition
370 len,
371 _phantom: PhantomData,
372 }
373 }
374
375 /// Constructs a new [root](crate#root) `UniqueSrc` of the given length where each element is produced by calling `f` with that element's index while walking forward through the slice.
376 ///
377 /// This essentially the same as writing
378 /// ```text
379 /// UniqueSrc::from_array([f(0), f(1), f(2), ..., f(len - 2), f(len - 1)])
380 /// ```
381 /// and is similar to `(0..len).map(f)`, just for `UniqueSrc`s rather than iterators.
382 ///
383 /// If `len == 0`, this produces an empty `UniqueSrc` without ever calling `f`.
384 ///
385 /// ```rust
386 /// use slice_rc::UniqueSrc;
387 ///
388 /// let slice = UniqueSrc::from_fn(5, |i| i);
389 /// assert_eq!(*slice, [0, 1, 2, 3, 4]);
390 ///
391 /// let slice2 = UniqueSrc::from_fn(8, |i| i * 2);
392 /// assert_eq!(*slice2, [0, 2, 4, 6, 8, 10, 12, 14]);
393 ///
394 /// let bool_slice = UniqueSrc::from_fn(5, |i| i % 2 == 0);
395 /// assert_eq!(*bool_slice, [true, false, true, false, true]);
396 /// ```
397 ///
398 /// You can also capture things, so you can use closures with mutable state.
399 /// The slice is generated in ascending index order, starting from the front and going towards the back.
400 /// ```rust
401 /// # use slice_rc::UniqueSrc;
402 /// let mut state = 1;
403 /// let s = UniqueSrc::from_fn(6, |_| { let x = state; state *= 2; x });
404 /// assert_eq!(*s, [1, 2, 4, 8, 16, 32]);
405 /// ```
406 ///
407 /// # Panics
408 ///
409 /// Panics if `f` panics; in this event, any elements that have been initialized will be properly dropped.
410 /// ```rust
411 /// # use slice_rc::UniqueSrc;
412 /// # use std::cell::Cell;
413 /// thread_local! {
414 /// static DROPPED: Cell<usize> = Cell::new(0);
415 /// }
416 ///
417 /// struct Droppable;
418 ///
419 /// impl Drop for Droppable {
420 /// fn drop(&mut self) {
421 /// DROPPED.with(|dropped| dropped.update(|x| x + 1));
422 /// }
423 /// }
424 ///
425 /// let _ = std::panic::catch_unwind(|| {
426 /// UniqueSrc::from_fn(10, |i| {
427 /// if i >= 5 { panic!() }
428 /// Droppable
429 /// })
430 /// });
431 ///
432 /// assert_eq!(DROPPED.get(), 5);
433 /// ```
434 #[inline]
435 pub fn from_fn<F: FnMut(usize) -> T>(len: usize, f: F) -> UniqueSrc<[T]> {
436 UninitSrc::new(len).init_unique_from_fn(f)
437 }
438
439 /// Constructs a new [root](crate#root) `UniqueSrc` of the given length where each element is produced by calling `f` with a root [`WeakSrc`] pointer to the new allocation and that element's index while walking forward through the slice.
440 ///
441 /// This method is like [`UniqueSrc::from_fn`], but in this the function `f` is passed a root [`WeakSrc`] pointer to the allocation to allow constructing self-referential elements.
442 ///
443 /// This is a convienience method for a specific subset of behavior that can be obtained via [`UninitSrc`].
444 ///
445 /// ```rust
446 /// use slice_rc::{Src, UniqueSrc, WeakSrc};
447 ///
448 /// struct S {
449 /// val: usize,
450 /// root: WeakSrc<[S]>,
451 /// }
452 ///
453 /// let root = UniqueSrc::cyclic_from_fn(5, |root, i| S {
454 /// val: i * 2,
455 /// root: root.clone(),
456 /// });
457 ///
458 /// assert_eq!(root.iter().map(|s| s.val).collect::<Vec<_>>(), vec![0, 2, 4, 6, 8]);
459 ///
460 /// let root = UniqueSrc::into_shared(root);
461 ///
462 /// assert!(root.iter().all(|s| Src::ptr_eq(&root, &s.root.upgrade().unwrap())));
463 /// ```
464 ///
465 /// Note: it should be possible to obtain a weak to just the current element that is being constructed via `weak.slice(i)`,
466 /// but currently a [`WeakSrc`] cannot be sliced while it is non-upgradeable (as it is in this case).
467 /// This is a known issue that will be fixed in the future.
468 pub fn cyclic_from_fn<F: FnMut(&WeakSrc<[T]>, usize) -> T>(len: usize, mut f: F) -> UniqueSrc<[T]> {
469 let this = UninitSrc::new(len);
470 let weak = this.downgrade();
471 this.init_unique_from_fn(|i| f(&weak, i))
472 }
473
474 /// Constructs a new [root](crate#root) `UniqueSrc` from the given iterator.
475 ///
476 /// This method is essentially shorthand for
477 /// ```rust
478 /// use slice_rc::UniqueSrc;
479 ///
480 /// # fn f<T>(iter: impl IntoIterator<Item = T, IntoIter: std::iter::ExactSizeIterator>) -> UniqueSrc<[T]> {
481 /// let mut iter = iter.into_iter();
482 /// UniqueSrc::from_fn(iter.len(), |_| iter.next().unwrap())
483 /// # }
484 /// ```
485 ///
486 /// The iterator must be [`ExactSizeIterator`] because `UniqueSrc`s cannot be resized,
487 /// so the number of elements must be known at allocation-time, i.e., before any of the elements are initialized.
488 /// If you want to use a non-[`ExactSizeIterator`], use <code>iter.[collect](Iterator::collect)::\<[Vec]\<_>>()</code>.
489 #[inline]
490 pub fn from_iter<I: IntoIterator<Item = T, IntoIter: ExactSizeIterator>>(iter: I) -> UniqueSrc<[T]> {
491 let mut iter = iter.into_iter();
492 UniqueSrc::from_fn(iter.len(), |_| iter.next().unwrap())
493 }
494
495 /// Constructs a new [root](crate#root) `UniqueSrc` from the given array.
496 ///
497 /// This method is effectively equivalent to passing an array to [`UniqueSrc::from_iter`], but it is more efficient.
498 /// As such, it is effectively shorthand for <code>UniqueSrc::[from_fn](N, |i| values\[i])</code>, but again, more efficient
499 /// (though not by enough to make <code>UniqueSrc::from_array([array::from_fn]::<_, N, _>(f))</code> any better than <code>UniqueSrc::[from_fn](N, f)</code>).
500 ///
501 /// Note that the my assertions about efficiency are not based any kind of benchmarking,
502 /// just the fact that this method uses a single [`ptr::write`] where [`UniqueSrc::from_fn`] and [`UniqueSrc::from_iter`] use `N` arbitrary function calls and `N` [`ptr::write`]s.
503 /// As <code>[array::from_fn]</code> re-introduces at least the `N` arbitrary function calls, its difference (again, without benchmarking) is negligible.
504 ///
505 /// [from_fn]: UniqueSrc::from_fn
506 /// [`ptr::write`]: std::ptr::write
507 /// [array::from_fn]: std::array::from_fn
508 pub fn from_array<const N: usize>(values: [T; N]) -> UniqueSrc<[T]> {
509 let header = InnerHeader::new_inner::<T, AllocUninit>(N);
510 // SAFETY:
511 // * we just got this from InnerHeader::new_inner::<T>
512 // * no one else has seen the ptr yet, so the read/write requirements are fine
513 let start = unsafe { InnerHeader::get_body_ptr::<T>(header) };
514 // SAFETY: no one else has seen the body, so write is fine; InnerHeader::new_inner::<T>(N) guarantees N elements, so we definitely have room for [T; N]
515 unsafe { start.cast().write(values) };
516 UniqueSrc {
517 // the safety invariant of _.header is fulfilled by definition
518 header,
519 // with start.write(_), the safety invariant of _.start is fulfilled by definition
520 start,
521 // the safety invariant of _.len is fulfilled by definition
522 len: N,
523 _phantom: PhantomData,
524 }
525 }
526
527 /// Constructs a new [root](crate#root) `UniqueSrc` of the given length where each element is the type's [default](Default::default).
528 ///
529 /// This method is essentially equivalent to <code>UniqueSrc::[from_fn](UniqueSrc::from_fn)(len, |_| [Default::default]\())</code>.
530 #[inline]
531 pub fn from_default(len: usize) -> UniqueSrc<[T]> where T: Default {
532 UniqueSrc::from_fn(len, |_| Default::default())
533 }
534
535 /// Constructs a new [root](crate#root) `UniqueSrc` of the given length where each element is a clone of `value`.
536 ///
537 /// This method is essentially equivalent to <code>UniqueSrc::[from_fn](UniqueSrc::from_fn)(len, |_| value.[clone](Clone::clone)())</code>.
538 #[inline]
539 pub fn filled(len: usize, value: &T) -> UniqueSrc<[T]> where T: Clone {
540 UniqueSrc::from_fn(len, |_| value.clone())
541 }
542
543 /// Constructs a new [root](crate#root) `UniqueSrc` of the given length where each element is a clone of the value returned from `f`.
544 /// `f` is passed a root [`WeakSrc`] pointer to the allocation; this can be used to make self-referential structures.
545 ///
546 /// ```rust
547 /// use slice_rc::{Src, UniqueSrc, WeakSrc};
548 ///
549 /// #[derive(Clone)]
550 /// struct S {
551 /// val: i32,
552 /// root: WeakSrc<[S]>,
553 /// }
554 ///
555 /// let root = UniqueSrc::filled_cyclic(5, |root| S { val: 42, root: root.clone() });
556 ///
557 /// assert!(root.iter().all(|s| s.val == 42));
558 ///
559 /// let root = UniqueSrc::into_shared(root);
560 ///
561 /// assert!(root.iter().all(|s| Src::ptr_eq(&root, &s.root.upgrade().unwrap())));
562 /// ```
563 pub fn filled_cyclic<F: FnOnce(&WeakSrc<[T]>) -> T>(len: usize, f: F) -> UniqueSrc<[T]> where T: Clone {
564 let this = UninitSrc::new(len);
565 let weak = this.downgrade();
566 this.init_unique_filled(&f(&weak))
567 }
568
569 /// Constructs a new [root](crate#root) `UniqueSrc` as a clone of the given slice.
570 ///
571 /// This method is essentially shorthand for <code>UniqueSrc::[from_fn](UniqueSrc::from_fn)(values.[len](slice::len)(), |i| values\[i].clone())</code>,
572 /// but without the implicit bounds checking for slice indexing.
573 #[inline]
574 pub fn cloned(values: &[T]) -> UniqueSrc<[T]> where T: Clone {
575 UniqueSrc::from_fn(values.len(), |i| {
576 // SAFETY: i ranges from 0..len==src.len()
577 unsafe { values.get_unchecked(i) }.clone()
578 })
579 }
580
581 /// Constructs a new [root](crate#root) `UniqueSrc` as a copy of the given slice.
582 ///
583 /// This method is functionally shorthand for <code>UniqueSrc::[from_fn](UniqueSrc::from_fn)(values.[len](slice::len)(), |i| values\[i])</code>,
584 /// but without the implicit bounds checking for slice indexing.
585 ///
586 /// This method is fairly efficient, as it is basically just an allocation (requisite for any `UniqueSrc` constructor) and a [`memcpy`](std::ptr::copy_nonoverlapping).
587 #[inline]
588 pub fn copied(values: &[T]) -> UniqueSrc<[T]> where T: Copy {
589 let len = values.len();
590 let header = InnerHeader::new_inner::<T, AllocUninit>(len);
591 // SAFETY:
592 // * we just got this from InnerHeader::new_inner::<T>
593 // * no one else has seen the ptr yet, so the read/write requirements are fine
594 let start = unsafe { InnerHeader::get_body_ptr::<T>(header) };
595 let values = NonNull::from_ref(values).cast();
596 // SAFETY:
597 // * values is from a reference, and is therefore valid
598 // * InnerHeader::new_inner::<T>(len) guarantees that start is valid for len * size_of::<T>() bytes and aligned for T
599 // * start just came from a new allocation, and therefore doesn't overlap with a slice that was passed into this function
600 unsafe { values.copy_to_nonoverlapping(start, len); }
601 UniqueSrc {
602 // the safety invariant of _.header is fulfilled by definition
603 header,
604 // with values.copy_to_nonoverlapping(_, _), the safety invariant of _.start is fulfilled by definition
605 start,
606 // the safety invariant of _.len is fulfilled by definition
607 len,
608 _phantom: PhantomData,
609 }
610 }
611
612}
613
614impl<T> UniqueSrc<MaybeUninit<T>> {
615
616 /// Converts to `UniqueSrc<T>`.
617 ///
618 /// # Safety
619 ///
620 /// As with [`MaybeUninit::assume_init`], it is up to the caller to guarantee that the inner value really is in an initialized state.
621 /// Calling this when the content is not yet fully initialized causes immediate undefined behavior.
622 ///
623 /// # Examples
624 ///
625 /// ```rust
626 /// use slice_rc::UniqueSrc;
627 ///
628 /// let zero = UniqueSrc::<i32>::single_zeroed();
629 /// let zero = unsafe { zero.assume_init() };
630 ///
631 /// assert_eq!(*zero, 0);
632 /// ```
633 pub unsafe fn assume_init(self) -> UniqueSrc<T> {
634 // TODO: rephrase the safety requirements for InnerHeader to explicitly allow punning between T and type with T-like layout
635 let this = UniqueSrc {
636 // SAFETY: self.header has *almost* the same safety invariant as this.header: the only difference is that self uses MaybeUninit<T> where this expects T
637 header: self.header,
638 // SAFETY: self.start has *almost* the same safety invariant as this.start: the only difference is that self uses MaybeUninit<T> where this expects T
639 start: self.start.cast(),
640 // SAFETY: self.len has *almost* the same safety invariant as this.len: the only difference is that self uses MaybeUninit<T> where this expects T
641 len: self.len,
642 _phantom: PhantomData,
643 };
644 forget(self);
645 this
646 }
647
648}
649
650impl<T> UniqueSrc<[MaybeUninit<T>]> {
651
652 /// Converts to `UniqueSrc<[T]>`.
653 ///
654 /// # Safety
655 ///
656 /// As with [`MaybeUninit::assume_init`], it is up to the caller to guarantee that the inner value really is in an initialized state.
657 /// Calling this when the content is not yet fully initialized causes immediate undefined behavior.
658 ///
659 /// # Examples
660 ///
661 /// ```rust
662 /// use slice_rc::UniqueSrc;
663 ///
664 /// let zeroes = UniqueSrc::<[i32]>::new_zeroed(3);
665 /// let zeroes = unsafe { zeroes.assume_init() };
666 ///
667 /// assert_eq!(*zeroes, [0, 0, 0]);
668 /// ```
669 pub unsafe fn assume_init(self) -> UniqueSrc<[T]> {
670 // TODO: rephrase the safety requirements for InnerHeader to explicitly allow punning between T and type with T-like layout
671 let this = UniqueSrc {
672 // SAFETY: self.header has *almost* the same safety invariant as this.header: the only difference is that self uses MaybeUninit<T> where this expects T
673 header: self.header,
674 // SAFETY: self.start has *almost* the same safety invariant as this.start: the only difference is that self uses MaybeUninit<T> where this expects T
675 start: self.start.cast(),
676 // SAFETY: self.len has *almost* the same safety invariant as this.len: the only difference is that self uses MaybeUninit<T> where this expects T
677 len: self.len,
678 _phantom: PhantomData,
679 };
680 forget(self);
681 this
682 }
683
684}
685
686impl UniqueSrc<str> {
687
688 /// Constructs a new [`root`](crate#root) `UniqueSrc` as a copy of the given string.
689 ///
690 /// ```rust
691 /// use slice_rc::UniqueSrc;
692 ///
693 /// let hello = UniqueSrc::new("Hello World!");
694 ///
695 /// assert_eq!(&*hello, "Hello World!");
696 /// ```
697 #[inline]
698 pub fn new(s: impl AsRef<str>) -> UniqueSrc<str> {
699 let s = s.as_ref();
700 let this = UniqueSrc::copied(s.as_bytes());
701 // SAFETY: the bytes here came from a str, which already upholds the UTF-8 safety invariant
702 unsafe { UniqueSrc::from_utf8_unchecked(this) }
703 }
704
705 /// Converts an `UniqueSrc` of bytes to a string `UniqueSrc`.
706 ///
707 /// [`str`] and [`[u8]`](slice) are both slices of bytes, so this function converts between the two.
708 /// Not all byte slices are valid string slices, however: [`str`] must be valid UTF-8.
709 /// This method checks to ensure that the bytes are valid UTF-8, and then does the conversion.
710 ///
711 /// If you are sure that the byte slice is valid UTF-8, and you don't want to incur the overhead of the validity check,
712 /// there is an unsafe version of this method, [`from_utf8_unchecked`](Src::from_utf8_unchecked),
713 /// which has the same behavior but skips the check.
714 ///
715 /// # Errors
716 ///
717 /// Returns `Err` if the slice is not UTF-8 with a description as to why the provided slice is not UTF-8.
718 ///
719 /// # Examples
720 ///
721 /// Basic usage:
722 ///
723 /// ```rust
724 /// use slice_rc::UniqueSrc;
725 ///
726 /// let sparkle_heart = UniqueSrc::from_array([240, 159, 146, 150]);
727 ///
728 /// let sparkle_heart = UniqueSrc::from_utf8(sparkle_heart)?;
729 ///
730 /// assert_eq!("💖", &*sparkle_heart);
731 /// # Ok::<_, std::str::Utf8Error>(())
732 /// ```
733 ///
734 /// Incorrect bytes:
735 ///
736 /// ```rust
737 /// # use slice_rc::UniqueSrc;
738 /// let sparkle_heart = UniqueSrc::from_array([0, 159, 146, 150]);
739 ///
740 /// assert!(UniqueSrc::from_utf8(sparkle_heart).is_err());
741 /// ```
742 #[inline]
743 pub fn from_utf8(v: UniqueSrc<[u8]>) -> Result<UniqueSrc<str>, Utf8Error> {
744 let _: &str = <str>::from_utf8(&*v)?;
745 // SAFETY: <str>::from_utf8() guarantees that the contents are UTF-8
746 Ok(unsafe { UniqueSrc::from_utf8_unchecked(v) })
747 }
748
749 /// Converts an `UniqueSrc` of bytes to a string `UniqueSrc` without checking that the string contains valid UTF-8.
750 ///
751 /// See the safe version, [`from_utf8`](UniqueSrc::from_utf8), for more information.
752 ///
753 /// # Safety
754 ///
755 /// The bytes passed in must be valid UTF-8.
756 ///
757 /// # Examples
758 ///
759 /// ```rust
760 /// use slice_rc::UniqueSrc;
761 ///
762 /// let sparkle_heart = UniqueSrc::from_array([240, 159, 146, 150]);
763 ///
764 /// let sparkle_heart = unsafe { UniqueSrc::from_utf8_unchecked(sparkle_heart) };
765 ///
766 /// assert_eq!("💖", &*sparkle_heart);
767 /// ```
768 #[inline]
769 pub unsafe fn from_utf8_unchecked(v: UniqueSrc<[u8]>) -> UniqueSrc<str> {
770 // TODO: rephrase the safety requirements for InnerHeader to explicitly allow punning between T and type with T-like layout
771 let this = UniqueSrc {
772 // SAFETY: v.header has *almost* the same safety invariant as this.header: the only difference is that v uses [u8] where this expects str;
773 // the pun from [u8] to str adds the safety requirement that v's content is valid UTF-8, but this requirement is passed on to the caller
774 header: v.header,
775 // SAFETY: v.start has *almost* the same safety invariant as this.start: the only difference is that v uses [u8] where this expects str;
776 // the pun from [u8] to str adds the safety requirement that v's content is valid UTF-8, but this requirement is passed on to the caller
777 start: v.start,
778 // SAFETY: v.len has *almost* the same safety invariant as this.len: the only difference is that v uses [u8] where this expects str;
779 // the pun from [u8] to str adds the safety requirement that v's content is valid UTF-8, but this requirement is passed on to the caller
780 len: v.len,
781 _phantom: PhantomData,
782 };
783 forget(v);
784 this
785 }
786
787 /// Converts a string `UniqueSrc` to a `UniqueSrc` of bytes.
788 /// To convert the the bytes back to a string, use the [`from_utf8`](UniqueSrc::from_utf8) method.
789 ///
790 /// # Examples
791 ///
792 /// ```rust
793 /// use slice_rc::UniqueSrc;
794 ///
795 /// let bytes = UniqueSrc::as_bytes(UniqueSrc::new("bors"));
796 /// assert_eq!(b"bors", &*bytes);
797 /// ```
798 #[inline]
799 pub fn as_bytes(this: UniqueSrc<str>) -> UniqueSrc<[u8]> {
800 // TODO: rephrase the safety requirements for InnerHeader to explicitly allow punning between T and type with T-like layout
801 let this2 = UniqueSrc {
802 // SAFETY: this.header has *almost* the same safety invariant as this2.header: the only difference is that this uses str where this2 expects [u8];
803 // the pun from str to [u8] relaxes the safety requirement that this's content is valid UTF-8
804 header: this.header,
805 // SAFETY: this.start has *almost* the same safety invariant as this2.start: the only difference is that this uses str where this2 expects [u8];
806 // the pun from str to [u8] relaxes the safety requirement that this's content is valid UTF-8
807 start: this.start,
808 // SAFETY: this.len has *almost* the same safety invariant as this2.len: the only difference is that this uses str where this2 expects [u8];
809 // the pun from str to [u8] relaxes the safety requirement that this's content is valid UTF-8
810 len: this.len,
811 _phantom: PhantomData,
812 };
813 forget(this);
814 this2
815 }
816
817}
818
819impl<T: Default> Default for UniqueSrc<T> {
820
821 #[inline]
822 fn default() -> Self {
823 Self::single(T::default())
824 }
825
826}
827
828impl<T: SrcTarget + ?Sized> Deref for UniqueSrc<T> {
829
830 type Target = T;
831
832 #[inline]
833 fn deref(&self) -> &Self::Target {
834 T::get_unique(self)
835 }
836
837}
838
839impl<T: SrcTarget + ?Sized> DerefMut for UniqueSrc<T> {
840
841 #[inline]
842 fn deref_mut(&mut self) -> &mut Self::Target {
843 T::get_unique_mut(self)
844 }
845
846}
847
848impl<T: SrcTarget + ?Sized> Borrow<T> for UniqueSrc<T> {
849
850 #[inline]
851 fn borrow(&self) -> &T {
852 &**self
853 }
854
855}
856
857impl<T: SrcTarget + ?Sized> BorrowMut<T> for UniqueSrc<T> {
858
859 #[inline]
860 fn borrow_mut(&mut self) -> &mut T {
861 &mut **self
862 }
863
864}
865
866impl<T: SrcTarget + ?Sized> AsRef<T> for UniqueSrc<T> {
867
868 #[inline]
869 fn as_ref(&self) -> &T {
870 &**self
871 }
872
873}
874
875impl<T: SrcTarget + ?Sized> AsMut<T> for UniqueSrc<T> {
876
877 #[inline]
878 fn as_mut(&mut self) -> &mut T {
879 &mut **self
880 }
881
882}
883
884impl<T: SrcTarget + Index<I> + ?Sized, I> Index<I> for UniqueSrc<T> {
885
886 type Output = T::Output;
887
888 #[inline]
889 fn index(&self, index: I) -> &Self::Output {
890 &self.deref()[index]
891 }
892
893}
894
895impl<T: SrcTarget + IndexMut<I> + ?Sized, I> IndexMut<I> for UniqueSrc<T> {
896
897 #[inline]
898 fn index_mut(&mut self, index: I) -> &mut Self::Output {
899 &mut self.deref_mut()[index]
900 }
901
902}
903
904impl<T: Hash + SrcTarget + ?Sized> Hash for UniqueSrc<T> {
905
906 #[inline]
907 fn hash<H: Hasher>(&self, state: &mut H) {
908 T::hash(&**self, state);
909 }
910
911}
912
913impl<T: PartialEq<U> + SrcTarget + ?Sized, U: SrcTarget + ?Sized> PartialEq<UniqueSrc<U>> for UniqueSrc<T> {
914
915 #[inline]
916 fn eq(&self, other: &UniqueSrc<U>) -> bool {
917 T::eq(&**self, &**other)
918 }
919
920 #[inline]
921 fn ne(&self, other: &UniqueSrc<U>) -> bool {
922 T::ne(&**self, &**other)
923 }
924
925}
926
927impl<T: Eq + SrcTarget + ?Sized> Eq for UniqueSrc<T> {}
928
929impl<T: PartialOrd<U> + SrcTarget + ?Sized, U: SrcTarget + ?Sized> PartialOrd<UniqueSrc<U>> for UniqueSrc<T> {
930
931 #[inline]
932 fn ge(&self, other: &UniqueSrc<U>) -> bool {
933 T::ge(&**self, &**other)
934 }
935
936 #[inline]
937 fn gt(&self, other: &UniqueSrc<U>) -> bool {
938 T::gt(&**self, &**other)
939 }
940
941 #[inline]
942 fn le(&self, other: &UniqueSrc<U>) -> bool {
943 T::le(&**self, &**other)
944 }
945
946 #[inline]
947 fn lt(&self, other: &UniqueSrc<U>) -> bool {
948 T::lt(&**self, &**other)
949 }
950
951 #[inline]
952 fn partial_cmp(&self, other: &UniqueSrc<U>) -> Option<Ordering> {
953 T::partial_cmp(&**self, &**other)
954 }
955
956}
957
958impl<T: Ord + SrcTarget + ?Sized> Ord for UniqueSrc<T> {
959
960 #[inline]
961 fn cmp(&self, other: &Self) -> Ordering {
962 T::cmp(&**self, &**other)
963 }
964
965}
966
967impl<T: Debug + SrcTarget + ?Sized> Debug for UniqueSrc<T> {
968
969 #[inline]
970 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
971 T::fmt(self, f)
972 }
973
974}
975
976impl<T: SrcTarget + ?Sized> Pointer for UniqueSrc<T> {
977
978 #[inline]
979 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
980 Pointer::fmt(&self.start, f)
981 }
982
983}
984
985impl<T: SrcTarget + ?Sized> Drop for UniqueSrc<T> {
986
987 fn drop(&mut self) {
988 // the UninqueSrc doesn't hold a strong ref so that the weaks can't be upgraded, but for most purposes it is just a Src that is known to be the only one; so drop it as if it were one
989 self.header().inc_strong_count();
990 // SAFETY:
991 // * all constructor fns for Src initialize header from InnerHeader::new_inner::<T::Item>
992 // * all constructor fns for Src initialize the elements
993 // * the header is only accessed from InnerHeader::get_header
994 // * this is guaranteed to be the last strong reference, because UniqueSrc's invariant prevents any other strong references from existing
995 unsafe { InnerHeader::drop_strong::<T::Item>(self.header); }
996 }
997
998}
999
1000#[cfg(test)]
1001mod tests {
1002
1003 use std::{cell::Cell, mem::MaybeUninit, ops::{Deref, DerefMut}, panic::{catch_unwind, AssertUnwindSafe}, str::Utf8Error};
1004 use crate::*;
1005
1006 #[test]
1007 fn downgrade() {
1008 let u: UniqueSrc<[u8]> = UniqueSrc::from_default(3);
1009 let w: WeakSrc<[u8]> = UniqueSrc::downgrade(&u);
1010 assert!(w.upgrade().is_none());
1011 let s1: Src<[u8]> = UniqueSrc::into_shared(u);
1012 let s2: Src<[u8]> = w.upgrade().unwrap();
1013 assert_eq!(s1, s2);
1014 assert!(Src::ptr_eq(&s1, &s2));
1015 }
1016
1017 #[test]
1018 fn into_shared() {
1019 let u: UniqueSrc<[u8]> = UniqueSrc::from_array([1, 2, 3]);
1020 let s1: Src<[u8]> = UniqueSrc::into_shared(u);
1021 let s2: Src<[u8]> = s1.clone();
1022 assert_eq!(*s1, [1, 2, 3]);
1023 assert!(Src::ptr_eq(&s1, &s2));
1024 }
1025
1026 #[test]
1027 fn empty() {
1028 let u: UniqueSrc<[u8]> = UniqueSrc::empty();
1029 assert!(u.is_empty());
1030 assert_eq!(u.len(), 0);
1031 let u: UniqueSrc<str> = UniqueSrc::empty();
1032 assert!(u.is_empty());
1033 assert_eq!(u.len(), 0);
1034 }
1035
1036 #[test]
1037 fn len() {
1038 let u: UniqueSrc<[u8]> = UniqueSrc::from_default(0);
1039 assert_eq!(u.len(), 0);
1040 let u: UniqueSrc<[u8]> = UniqueSrc::from_default(1);
1041 assert_eq!(u.len(), 1);
1042 let u: UniqueSrc<[u8]> = UniqueSrc::from_default(17);
1043 assert_eq!(u.len(), 17);
1044 }
1045
1046 #[test]
1047 fn is_empty() {
1048 let u: UniqueSrc<[u8]> = UniqueSrc::from_default(0);
1049 assert!(u.is_empty());
1050 let u: UniqueSrc<[u8]> = UniqueSrc::from_default(1);
1051 assert!(!u.is_empty());
1052 let u: UniqueSrc<[u8]> = UniqueSrc::from_default(17);
1053 assert!(!u.is_empty());
1054 }
1055
1056 #[test]
1057 fn single() {
1058 let u: UniqueSrc<u8> = UniqueSrc::single(42);
1059 let s: Src<u8> = UniqueSrc::into_shared(u);
1060 assert!(Src::is_root(&s));
1061 let s: Src<[u8]> = Src::as_slice(&s);
1062 assert_eq!(s.len(), 1);
1063 }
1064
1065 #[test]
1066 fn single_cyclic() {
1067 { // non-cyclic
1068 let u: UniqueSrc<u8> = UniqueSrc::single_cyclic(|_| 42);
1069 assert_eq!(*u, 42);
1070 }
1071 { // cyclic
1072 struct S {
1073
1074 this: WeakSrc<S>,
1075 i: usize,
1076
1077 }
1078 let u: UniqueSrc<S> = UniqueSrc::single_cyclic(|weak| S { this: weak.clone(), i: 42 });
1079 assert_eq!(u.i, 42);
1080 let w: WeakSrc<S> = UniqueSrc::downgrade(&u);
1081 assert!(WeakSrc::ptr_eq(&u.this, &w));
1082 }
1083 }
1084
1085 #[test]
1086 fn single_uninit() {
1087 let mut u: UniqueSrc<MaybeUninit<u8>> = UniqueSrc::single_uninit();
1088 u.write(42);
1089 // SAFETY: just initialized this with u.write()
1090 let u: UniqueSrc<u8> = unsafe { u.assume_init() };
1091 assert_eq!(*u, 42);
1092 }
1093
1094 #[test]
1095 fn single_zeroed() {
1096 let u: UniqueSrc<MaybeUninit<u8>> = UniqueSrc::single_zeroed();
1097 // SAFETY: u8 is a zeroable type
1098 let u: UniqueSrc<u8> = unsafe { u.assume_init() };
1099 assert_eq!(*u, 0);
1100 }
1101
1102 #[test]
1103 fn as_slice() {
1104 let u: UniqueSrc<u8> = UniqueSrc::single(42);
1105 let u: UniqueSrc<[u8]> = UniqueSrc::as_slice(u);
1106 assert_eq!([42], *u);
1107 }
1108
1109 #[test]
1110 fn new_uninit() {
1111 let mut u: UniqueSrc<[MaybeUninit<u8>]> = UniqueSrc::new_uninit(3);
1112 assert_eq!(u.len(), 3);
1113 for (i, elem) in u.iter_mut().enumerate() {
1114 elem.write(i as _);
1115 }
1116 // SAFETY: just initialized it with all the elem.write()s
1117 let u: UniqueSrc<[u8]> = unsafe { u.assume_init() };
1118 assert_eq!(*u, [0, 1, 2]);
1119 }
1120
1121 #[test]
1122 fn new_zeroed() {
1123 let u: UniqueSrc<[MaybeUninit<u8>]> = UniqueSrc::new_zeroed(3);
1124 assert_eq!(u.len(), 3);
1125 // SAFETY: u8 is a zeroable type
1126 let u: UniqueSrc<[u8]> = unsafe { u.assume_init() };
1127 assert_eq!(*u, [0, 0, 0]);
1128 }
1129
1130 #[test]
1131 fn from_fn() {
1132 { // normal
1133 let u: UniqueSrc<[usize]> = UniqueSrc::from_fn(3, |i| i * 2);
1134 assert_eq!(*u, [0, 2, 4]);
1135 }
1136 { // panic
1137 let drop_flags: [_; 6] = std::array::from_fn(|_| AssertUnwindSafe(Cell::new(false)));
1138 struct DropFlagger<'a>(&'a Cell<bool>);
1139 impl Drop for DropFlagger<'_> {
1140
1141 fn drop(&mut self) {
1142 self.0.update(|v| !v)
1143 }
1144
1145 }
1146 let _: Result<_, _> = catch_unwind(|| {
1147 let _: UniqueSrc<[DropFlagger<'_>]> = UniqueSrc::from_fn(drop_flags.len(), |i| {
1148 if i >= 3 { panic!() }
1149 DropFlagger(&drop_flags[i])
1150 });
1151 });
1152 assert!(drop_flags[..3].iter().map(Deref::deref).all(Cell::get));
1153 assert!(!drop_flags[3..].iter().map(Deref::deref).any(Cell::get));
1154 }
1155 }
1156
1157 #[test]
1158 fn cyclic_from_fn() {
1159 { // normal, not cyclic
1160 let u: UniqueSrc<[usize]> = UniqueSrc::cyclic_from_fn(3, |_, i| i * 2);
1161 assert_eq!(*u, [0, 2, 4]);
1162 }
1163 { // normal, cyclic
1164 struct S {
1165
1166 all: WeakSrc<[S]>,
1167 i: usize,
1168
1169 }
1170 let u: UniqueSrc<[S]> = UniqueSrc::cyclic_from_fn(3, |w, i| S { all: w.clone(), i: i * 2 });
1171 assert_eq!(u[0].i, 0);
1172 assert_eq!(u[1].i, 2);
1173 assert_eq!(u[2].i, 4);
1174 assert!(u[0].all.upgrade().is_none());
1175 let s1: Src<[S]> = UniqueSrc::into_shared(u);
1176 let s2: Src<[S]> = s1[0].all.upgrade().unwrap();
1177 assert!(Src::ptr_eq(&s1, &s2));
1178 }
1179 { // panic
1180 let drop_flags: [_; 6] = std::array::from_fn(|_| AssertUnwindSafe(Cell::new(false)));
1181 struct DropFlagger<'a>(&'a Cell<bool>);
1182 impl Drop for DropFlagger<'_> {
1183
1184 fn drop(&mut self) {
1185 self.0.update(|v| !v)
1186 }
1187
1188 }
1189 let _: Result<_, _> = catch_unwind(|| {
1190 let _: UniqueSrc<[DropFlagger<'_>]> = UniqueSrc::cyclic_from_fn(drop_flags.len(), |_, i| {
1191 if i >= 3 { panic!() }
1192 DropFlagger(&drop_flags[i])
1193 });
1194 });
1195 assert!(drop_flags[..3].iter().map(Deref::deref).all(Cell::get));
1196 assert!(!drop_flags[3..].iter().map(Deref::deref).any(Cell::get));
1197 }
1198 }
1199
1200 #[test]
1201 fn from_iter() {
1202 let u: UniqueSrc<[u8]> = UniqueSrc::from_iter(vec![1, 2, 3].into_iter().map(|i| i * 2));
1203 assert_eq!(*u, [2, 4, 6]);
1204 }
1205
1206 #[test]
1207 fn from_array() {
1208 let u: UniqueSrc<[u8]> = UniqueSrc::from_array([1, 2, 3]);
1209 assert_eq!(*u, [1, 2, 3]);
1210 }
1211
1212 #[test]
1213 fn from_default() {
1214 #[derive(Copy, Clone, Eq, PartialEq, Debug)]
1215 struct D42(u8);
1216 impl Default for D42 {
1217
1218 fn default() -> Self {
1219 Self(42)
1220 }
1221
1222 }
1223 let u: UniqueSrc<[u8]> = UniqueSrc::from_default(3);
1224 assert_eq!(*u, [0, 0, 0]);
1225 let u: UniqueSrc<[D42]> = UniqueSrc::from_default(3);
1226 assert_eq!(*u, [D42(42), D42(42), D42(42)]);
1227 }
1228
1229 #[test]
1230 fn filled() {
1231 let u: UniqueSrc<[u8]> = UniqueSrc::filled(3, &42);
1232 assert_eq!(*u, [42, 42, 42]);
1233 }
1234
1235 #[test]
1236 fn filled_cyclic() {
1237 { // non-cyclic
1238 let u: UniqueSrc<[u8]> = UniqueSrc::filled_cyclic(3, |_| 42);
1239 assert_eq!(*u, [42, 42, 42]);
1240 }
1241 { // cyclic
1242 #[derive(Clone)]
1243 struct S {
1244
1245 all: WeakSrc<[S]>,
1246 i: usize,
1247
1248 }
1249 let u: UniqueSrc<[S]> = UniqueSrc::filled_cyclic(3, |weak| S { all: weak.clone(), i: 42 });
1250 assert_eq!(u[0].i, 42);
1251 assert_eq!(u[1].i, 42);
1252 assert_eq!(u[2].i, 42);
1253 let w: WeakSrc<[S]> = UniqueSrc::downgrade(&u);
1254 assert!(WeakSrc::ptr_eq(&u[0].all, &w));
1255 }
1256 }
1257
1258 #[test]
1259 fn cloned() {
1260 #[derive(Clone, Eq, PartialEq, Debug)]
1261 struct NonCopy(u8);
1262 let u: UniqueSrc<[NonCopy]> = UniqueSrc::cloned(&[NonCopy(1), NonCopy(2), NonCopy(3)]);
1263 assert_eq!(*u, [NonCopy(1), NonCopy(2), NonCopy(3)]);
1264 }
1265
1266 #[test]
1267 fn copied() {
1268 let u: UniqueSrc<[u8]> = UniqueSrc::copied(&[1, 2, 3]);
1269 assert_eq!(*u, [1, 2, 3]);
1270 }
1271
1272 #[test]
1273 fn assume_init_single() {
1274 let u: UniqueSrc<MaybeUninit<u8>> = UniqueSrc::single_zeroed();
1275 // SAFETY: u8 is a zeroable type
1276 let u: UniqueSrc<u8> = unsafe { u.assume_init() };
1277 assert_eq!(*u, 0);
1278 }
1279
1280 #[test]
1281 fn assume_init_slice() {
1282 let u: UniqueSrc<[MaybeUninit<u8>]> = UniqueSrc::new_zeroed(3);
1283 // SAFETY: u8 is a zeroable type
1284 let u: UniqueSrc<[u8]> = unsafe { u.assume_init() };
1285 assert_eq!(*u, [0, 0, 0]);
1286 }
1287
1288 #[test]
1289 fn new() {
1290 let u: UniqueSrc<str> = UniqueSrc::new("Hello World!");
1291 assert_eq!(&*u, "Hello World!");
1292 }
1293
1294 #[test]
1295 fn from_utf8() {
1296 { // UTF-8
1297 let u: UniqueSrc<[u8]> = UniqueSrc::copied(b"Hello World!");
1298 let u: UniqueSrc<str> = UniqueSrc::from_utf8(u).unwrap();
1299 assert_eq!(&*u, "Hello World!");
1300 }
1301 { // not UTF-8
1302 let u: UniqueSrc<[u8]> = UniqueSrc::copied(&[0xFF]);
1303 let _: Utf8Error = UniqueSrc::from_utf8(u).unwrap_err();
1304 }
1305 }
1306
1307 #[test]
1308 fn from_utf8_unchecked() {
1309 let u: UniqueSrc<[u8]> = UniqueSrc::copied(b"Hello World!");
1310 // SAFETY: just got the bytes from a str
1311 let u: UniqueSrc<str> = unsafe { UniqueSrc::from_utf8_unchecked(u) };
1312 assert_eq!(&*u, "Hello World!");
1313 }
1314
1315 #[test]
1316 fn as_bytes() {
1317 let u: UniqueSrc<str> = UniqueSrc::new("Hello World!");
1318 let u: UniqueSrc<[u8]> = UniqueSrc::as_bytes(u);
1319 assert_eq!(&*u, b"Hello World!");
1320 }
1321
1322 #[test]
1323 fn deref() {
1324 let u: UniqueSrc<[u8]> = UniqueSrc::from_array([1, 2, 3]);
1325 assert_eq!(Deref::deref(&u), &[1, 2, 3]);
1326 }
1327
1328 #[test]
1329 fn deref_mut() {
1330 let mut u: UniqueSrc<[i8]> = UniqueSrc::from_array([1, 2, 3]);
1331 assert_eq!(DerefMut::deref_mut(&mut u), &mut [1, 2, 3]);
1332 u[0] -= 4;
1333 u[1] = 42;
1334 u[2] *= 2;
1335 assert_eq!(DerefMut::deref_mut(&mut u), &mut [-3, 42, 6]);
1336 }
1337
1338 #[test]
1339 fn drop() {
1340 let drop_flags: [_; 3] = std::array::from_fn(|_| Cell::new(false));
1341 struct DropFlagger<'a>(&'a Cell<bool>);
1342 impl Drop for DropFlagger<'_> {
1343
1344 fn drop(&mut self) {
1345 self.0.update(|v| !v)
1346 }
1347
1348 }
1349 assert!(!drop_flags.iter().any(Cell::get));
1350 let u: UniqueSrc<[DropFlagger<'_>]> = UniqueSrc::from_iter(drop_flags.iter().map(DropFlagger));
1351 assert!(!drop_flags.iter().any(Cell::get));
1352 std::mem::drop(u);
1353 assert!(drop_flags.iter().all(Cell::get));
1354 }
1355
1356}