slice_rc/strong.rs
1use std::{borrow::Borrow, cmp::Ordering, fmt::{self, Debug, Formatter, Pointer}, hash::{Hash, Hasher}, marker::PhantomData, mem::{forget, MaybeUninit}, ops::{Bound, Deref, Index}, ptr::NonNull, str::Utf8Error};
2
3use crate::{InnerHeader, SrcIndex, SrcSlice, SrcTarget, UninitSrc, UniqueSrc, WeakSrc};
4
5/// A single-threaded sliceable reference-counting pointer. 'Src' stands for 'Slice Reference Counted'.
6///
7/// See [`std::rc`] for details about general reference-counting pointers.
8///
9/// `Src` is a variation on [`Rc`](std::rc::Rc); the functionality that differentiates them can be accessed with the method [`Src::slice`].
10///
11/// Many of the inherent methods of `Src` are associated functions, which means that you have to call them as e.g.,
12/// [`Src::downgrade(&value)`](Src::downgrade) instead of `value.downgrade()`;
13/// this avoids conflicts with methods of the inner type `T`.
14/// However, some methods, e.g. [`Src::slice`], are permitted to remain as methods because the inner type is known not to have a conflicting method,
15/// and some, e.g. [`Src::len`], intentionally shadow a known method of the inner type because they use a more efficient computation for the same result.
16pub struct Src<T: SrcTarget + ?Sized> {
17
18 // SAFETY:
19 // requires:
20 // * initialized from InnerHeader::new_inner::<T::Item>(_)
21 pub(crate) header: NonNull<InnerHeader>,
22 // SAFETY:
23 // requires:
24 // * 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()
25 // * all body elements have been properly initialized (e.g., self.start.as_ref() will not cause UB)
26 pub(crate) start: NonNull<T::Item>,
27 // SAFETY:
28 // requires when T: SrcSlice:
29 // * self.start.add(self.len) <= InnerHeader::get_body_ptr::<T::Item>(self.header).add(InnerHeader::get_header(self.header).len())
30 // requires when T: Sized:
31 // * self.start < InnerHeader::get_body_ptr::<T::Item>(self.header).add(InnerHeader::get_header(self.header).len())
32 pub(crate) len: T::Len,
33 pub(crate) _phantom: PhantomData<*const T>,
34
35}
36
37impl<T: SrcTarget + ?Sized> Src<T> {
38
39 fn header(&self) -> &InnerHeader {
40 // SAFETY:
41 // * the invariant for self.header guarantees that it is from InnerHeader::new_inner::<T::Item>
42 // * the header is only accessed from InnerHeader::get_header
43 unsafe { InnerHeader::get_header(self.header) }
44 }
45
46 /// Returns `true` if the two `Src`s point to slices starting at the same location in memory, akin to [`ptr::eq`](std::ptr::eq).
47 ///
48 /// ```rust
49 /// use slice_rc::Src;
50 ///
51 /// let slice = Src::from_array([1, 2, 3]);
52 /// let same_slice = Src::clone(&slice);
53 /// let sub_slice = slice.slice(1..);
54 /// let other_slice = Src::from_array([1, 2, 3]);
55 ///
56 /// assert!(Src::ptr_eq(&slice, &same_slice));
57 /// assert!(!Src::ptr_eq(&slice, &sub_slice));
58 /// assert!(!Src::ptr_eq(&slice, &other_slice));
59 /// ```
60 ///
61 /// If `Src::ptr_eq(&a, &b)` returns true, then <code>Src::[same_root](Src::same_root)(&a, &b)</code> will also be true.
62 ///
63 /// The type parameter, `U`, is to allow `Src`s of different types that _could_ be of the same allocation, and therefore, _could_ be equal by pointer, to be compared, e.g.:
64 /// ```rust
65 /// # use slice_rc::Src;
66 /// let single: Src<i32> = Src::single(4);
67 /// let slice: Src<[i32]> = Src::as_slice(&single);
68 ///
69 /// assert!(Src::ptr_eq(&single, &slice));
70 /// ```
71 ///
72 /// Note that this method currently ignores the length of the slice:
73 /// ```rust
74 /// # use slice_rc::Src;
75 /// let root = Src::from_array([1, 2, 3]);
76 /// let first = root.slice(0);
77 ///
78 /// assert!(Src::ptr_eq(&root, &first));
79 ///
80 /// let mid_to_end_slice = root.slice(1..);
81 /// let mid_slice = root.slice(1..=1);
82 ///
83 /// assert!(Src::ptr_eq(&mid_to_end_slice, &mid_slice));
84 /// ```
85 /// It is undecided whether this behavior is desireable, and as such, it may change;
86 /// notably, [`Rc::ptr_eq`](std::rc::Rc::ptr_eq) does ignore metadata for `?Sized` types
87 /// (though that's irrelevant for slices because [`Rc`]s can only point to the whole slice, and therefore the length will always be the same for [`Rc`]s that point to the same allocation),
88 /// while [`ptr::eq`](std::ptr::eq) does consider the metadata (which causes inconsistent results for trait objects, but that is irrelevant here because `Src`s don't support trait objects).
89 ///
90 /// See also [`Src::same_root`].
91 ///
92 /// [`Rc`]: std::rc::Rc
93 #[inline]
94 pub fn ptr_eq<U: SrcTarget<Item = T::Item> + ?Sized>(this: &Src<T>, other: &Src<U>) -> bool {
95 this.start == other.start
96 }
97
98 /// Returns `true` if the two `Src`s share the same [root](crate#root) (i.e., they point to parts of the same allocation).
99 ///
100 /// ```rust
101 /// use slice_rc::Src;
102 ///
103 /// let slice = Src::from_array([1, 2, 3]);
104 /// let same_slice = Src::clone(&slice);
105 /// let other_slice = Src::from_array([1, 2, 3]);
106 ///
107 /// assert!(Src::same_root(&slice, &same_slice));
108 /// assert!(!Src::same_root(&slice, &other_slice));
109 /// ```
110 ///
111 /// Notably, neither slice has to be the root, nor do they need to overlap at all:
112 /// ```rust
113 /// # use slice_rc::Src;
114 /// let root = Src::from_array([1, 2, 3]);
115 /// let a = root.slice(..1);
116 /// let b = root.slice(2..);
117 ///
118 /// assert!(Src::same_root(&a, &b));
119 /// ```
120 ///
121 /// The type parameter, `U`, is to allow `Src`s of different types that _could_ share the same root, to be compared, e.g.:
122 /// ```rust
123 /// # use slice_rc::Src;
124 /// let single: Src<i32> = Src::single(4);
125 /// let slice: Src<[i32]> = Src::as_slice(&single);
126 ///
127 /// assert!(Src::same_root(&single, &slice));
128 /// ```
129 ///
130 /// This method ignores the length of the slices in question, but unlike [`Src::ptr_eq`], this will not change,
131 /// as the roots remains the same regardless of which parts of it are included in these slices.
132 ///
133 /// See also [`Src::ptr_eq`], [`Src::is_root`], and [`Src::root`].
134 #[inline]
135 pub fn same_root<U: SrcTarget<Item = T::Item> + ?Sized>(this: &Src<T>, other: &Src<U>) -> bool {
136 this.header == other.header
137 }
138
139 /// Returns `true` if this `Src` contains its [root](crate#root) (i.e., it references its entire allocation).
140 /// Notably, this `Src` does not have to be the first one that was initialized, it just has to cover the entire allocation.
141 ///
142 /// ```rust
143 /// use slice_rc::Src;
144 ///
145 /// let root = Src::from_array([1, 2, 3]);
146 /// let also_root = root.slice(..);
147 /// let slice = root.slice(1..);
148 ///
149 /// assert!(Src::is_root(&root));
150 /// assert!(Src::is_root(&also_root));
151 /// assert!(!Src::is_root(&slice));
152 /// ```
153 ///
154 /// See also [`Src::same_root`] and [`Src::root`].
155 #[inline]
156 pub fn is_root(this: &Src<T>) -> bool {
157 // SAFETY:
158 // * the invariant for this.header guarantees that it is from InnerHeader::new_inner::<T::Item>
159 // * the header is only accessed from InnerHeader::get_header
160 let root_start = unsafe { InnerHeader::get_body_ptr(this.header) };
161 this.start == root_start && T::len_as_usize(this.len) == this.header().len()
162 }
163
164 /// Creates a [`WeakSrc`] pointer to this slice.
165 /// The [`WeakSrc`] refers to the same slice as this `Src`, and therefore, refers to the [root](crate#root) if and only if this `Src` does.
166 ///
167 /// ```rust
168 /// use slice_rc::Src;
169 ///
170 /// let root = Src::from_array([1, 2, 3]);
171 ///
172 /// let weak_root = Src::downgrade(&root);
173 /// ```
174 pub fn downgrade(this: &Src<T>) -> WeakSrc<T> {
175 this.header().inc_weak_count();
176 WeakSrc {
177 // SAFETY: this.header's invariant implies _.header's invariant
178 header: this.header,
179 // SAFETY: this.header's invariant implies _.header's invariant
180 start: this.start,
181 // SAFETY: this.header's invariant implies _.header's invariant
182 len: this.len,
183 _phantom: PhantomData,
184 }
185 }
186
187 /// Gets the number of strong (`Src`) pointers to any part of this allocation.
188 ///
189 /// ```rust
190 /// use slice_rc::Src;
191 ///
192 /// let root = Src::from_array([1, 2, 3]);
193 /// let _slice = root.slice(1..);
194 ///
195 /// assert_eq!(2, Src::strong_count(&root));
196 /// ```
197 pub fn strong_count(this: &Src<T>) -> usize {
198 this.header().strong_count()
199 }
200
201 /// Gets the number of [`WeakSrc`] pointers to any part of this allocation.
202 ///
203 /// ```rust
204 /// use slice_rc::Src;
205 ///
206 /// let root = Src::from_array([1, 2, 3]);
207 /// let slice = root.slice(1..);
208 /// let _weak_slice = Src::downgrade(&slice);
209 ///
210 /// assert_eq!(1, Src::weak_count(&root));
211 /// ```
212 pub fn weak_count(this: &Src<T>) -> usize {
213 this.header().weak_count() - 1
214 }
215
216 /// Turns this `Src` into a [`UniqueSrc`], if it has only one strong reference.
217 ///
218 /// Otherwise, an [`Err`] is returned withe the same `Src` that was passed in.
219 ///
220 /// This will succeed even if there are outstanding weak references,
221 /// though those references will not be able to [`upgrade`](WeakSrc::upgrade) while this allocation is managed by a [`UniqueSrc`].
222 ///
223 /// ```rust
224 /// use slice_rc::Src;
225 ///
226 /// let x = Src::single(3);
227 /// assert_eq!(*Src::into_unique(x).unwrap(), 3);
228 ///
229 /// let x = Src::single(4);
230 /// let _y = Src::clone(&x);
231 /// assert_eq!(*Src::into_unique(x).unwrap_err(), 4);
232 /// ```
233 ///
234 /// See also [`Src::make_unique`].
235 ///
236 /// Note that this method (and [`Src::make_unique`]) can currently be used to construct non-[root](crate#root) [`UniqueSrc`]s;
237 /// this behavior has not been thouroghly considered and may be changed or removed in the future.
238 /// As it is, the [`UniqueSrc`] will retain unique ownership of the whole allocation, even the parts it doesn't contain.
239 /// This means that a [`WeakSrc`] to any part of the allocation will not be able to [`upgrade`](WeakSrc::upgrade),
240 /// even if that [`WeakSrc`] does not overlap with the [`UniqueSrc`].
241 pub fn into_unique(this: Src<T>) -> Result<UniqueSrc<T>, Src<T>> {
242 let header = this.header();
243 if header.strong_count() == 1 {
244 // decrease the strong count to 0, but don't drop;
245 // obviously, the UniqueSrc still needs the body to exist, so it shouldn't be dropped,
246 // but the strong count should be 0 so that the weak references can't upgrade (because that Src would be an alias of the UniqueSrc, which violates UniqueSrc's invariant)
247 header.dec_strong_count();
248 let this2 = UniqueSrc {
249 // SAFETY: this.header has the same safety invariant as this2.header, in addition to the requirement that no other strong Src has access to this allocation, which is checked by header.strong_count() == 1
250 header: this.header,
251 // SAFETY: this.start has the same safety invariant as this2.start
252 start: this.start,
253 // SAFETY: this.len has the same safety invariant as this2.len
254 len: this.len,
255 _phantom: PhantomData,
256 };
257 forget(this); // as stated above, don't drop; additionally, now that the strong count has already been set to 0, dropping this would actually cause a panic on debug and probably big problems on release because it would cause integer overflow
258 Ok(this2)
259 } else {
260 Err(this)
261 }
262 }
263
264 /// If this is the only strong reference to this allocation, then it is turned into a [`UniqueSrc`].
265 /// Otherwise, the contents are cloned and return in a new [`UniqueSrc`].
266 ///
267 /// This is somewhat like [`Rc::make_mut`](std::rc::Rc::make_mut), but with some subtle differences.
268 ///
269 /// ```rust
270 /// use slice_rc::{Src, UniqueSrc};
271 ///
272 /// let data = Src::single(5);
273 /// let mut data = Src::make_unique(data); // Won't clone anything
274 /// *data += 1;
275 /// let data = UniqueSrc::into_shared(data);
276 /// let other_data = Src::clone(&data); // Won't clone inner data
277 /// let mut data = Src::make_unique(data); // Clones inner data
278 /// *data += 1;
279 /// let data = UniqueSrc::into_shared(data);
280 /// let mut data = Src::make_unique(data); // Won't clone anything
281 /// *data += 1;
282 /// let data = UniqueSrc::into_shared(data);
283 /// let mut other_data = Src::make_unique(other_data); // Won't clone anything
284 /// *other_data *= 2;
285 /// let other_data = UniqueSrc::into_shared(other_data);
286 ///
287 /// // Now `data` and `other_data` point to different allocations.
288 /// assert_eq!(*data, 8);
289 /// assert_eq!(*other_data, 12);
290 /// ```
291 ///
292 /// If this is the only `Src` pointer to this allocation,
293 /// but there are some [`WeakSrc`] pointers, then the [`WeakSrc`] pointers will be carried over to the [`UniqueSrc`].
294 /// ```rust
295 /// # use slice_rc::{Src, UniqueSrc};
296 /// let data = Src::single(75);
297 /// let weak = Src::downgrade(&data);
298 ///
299 /// assert_eq!(75, *data);
300 /// assert_eq!(75, *weak.upgrade().unwrap());
301 ///
302 /// let mut data = Src::make_unique(data);
303 /// *data += 1;
304 ///
305 /// assert_eq!(76, *data);
306 /// assert!(weak.upgrade().is_none());
307 ///
308 /// let data = UniqueSrc::into_shared(data);
309 ///
310 /// assert_eq!(76, *data);
311 /// assert_eq!(76, *weak.upgrade().unwrap());
312 /// ```
313 /// However, if there are other `Src` pointers to this allocation, any [`WeakSrc`] pointers will remain with the old allocation.
314 /// ```rust
315 /// # use slice_rc::{Src, UniqueSrc};
316 /// let data = Src::single(75);
317 /// let other_data = Src::clone(&data);
318 /// let weak = Src::downgrade(&data);
319 ///
320 /// assert_eq!(75, *data);
321 /// assert_eq!(75, *other_data);
322 /// assert_eq!(75, *weak.upgrade().unwrap());
323 ///
324 /// let mut data = Src::make_unique(data);
325 /// *data += 1;
326 ///
327 /// assert_eq!(76, *data);
328 /// assert_eq!(75, *other_data);
329 /// assert_eq!(75, *weak.upgrade().unwrap());
330 ///
331 /// let data = UniqueSrc::into_shared(data);
332 ///
333 /// assert_eq!(76, *data);
334 /// assert_eq!(75, *other_data);
335 /// assert_eq!(75, *weak.upgrade().unwrap());
336 /// ```
337 ///
338 /// See also [`Src::into_unique`].
339 ///
340 /// Note that this method (and [`Src::into_unique`]) can currently be used to construct non-[root](crate#root) [`UniqueSrc`]s;
341 /// this behavior has not been thouroghly considered and may be changed or removed in the future.
342 /// As it is, the [`UniqueSrc`] will retain unique ownership of the whole allocation, even the parts it doesn't contain.
343 /// This means that a [`WeakSrc`] to any part of the allocation will not be able to [`upgrade`](WeakSrc::upgrade),
344 /// even if that [`WeakSrc`] does not overlap with the [`UniqueSrc`].
345 pub fn make_unique(this: Src<T>) -> UniqueSrc<T> where T::Item: Clone {
346 Src::into_unique(this).unwrap_or_else(|this| T::new_unique_from_clone(&*this))
347 }
348
349 /// Returns an `Src` pointer that refers to this `Src`'s [root](crate#root) (i.e., the entire allocation).
350 /// ```rust
351 /// use slice_rc::Src;
352 ///
353 /// let root = Src::from_array([1, 2, 3]);
354 /// let slice = root.slice(1..);
355 /// drop(root);
356 ///
357 /// assert_eq!(*slice, [2, 3]);
358 ///
359 /// let new_root = Src::root(&slice);
360 ///
361 /// assert_eq!(*new_root, [1, 2, 3]);
362 /// ```
363 ///
364 /// This method returns an <code>[Src]\<\[T::[Item](crate::SrcTarget::Item)]></code> rather than an <code>[Src]\<T></code> for two reasons:
365 /// * If <code>T: [Sized]</code>, then the root can only be a <code>[Src]\<T></code> if its total length is is `1`, which would prevent situations like this:
366 /// ```rust
367 /// # use slice_rc::Src;
368 /// let root: Src<[i32]> = Src::from_array([1, 2, 3]);
369 /// let slice: Src<i32> = root.slice(1);
370 /// let new_root: Src<[i32]> = Src::root(&slice);
371 ///
372 /// assert_eq!(*new_root, [1, 2, 3]);
373 /// ```
374 /// * If <code>T = [str]</code>, it could be a UTF-8 slice of a larger allocation that is not entirely UTF-8, which would violate the safety invariant of [`str`]:
375 /// ```rust
376 /// # use slice_rc::Src;
377 /// let root: Src<[u8]> = Src::copied(b"\xFFhello");
378 /// let s: Src<str> = Src::from_utf8(root.slice(1..)).unwrap();
379 /// let new_root: Src<[u8]> = Src::root(&s);
380 ///
381 /// assert_eq!(&*s, "hello");
382 /// assert!(Src::from_utf8(new_root).is_err());
383 /// ```
384 pub fn root(this: &Src<T>) -> Src<[T::Item]> {
385 let header = this.header();
386 // SAFETY:
387 // * the invariant for self.header guarantees that it is from InnerHeader::new_inner::<T::Item>
388 // * the header is only accessed from InnerHeader::get_header
389 let start = unsafe { InnerHeader::get_body_ptr::<T::Item>(this.header) };
390 header.inc_strong_count();
391 Src {
392 // SAFETY: self.header has the same safety invariant as this.header
393 header: this.header,
394 // SAFETY: start was just aquired from InnerHeader::get_body_ptr::<T::Item>(self.header), which, with the assertions, meets the safety requirement
395 start,
396 // SAFETY: header.len() meets the safety requirements by definition
397 len: header.len(),
398 _phantom: PhantomData,
399 }
400 }
401
402}
403
404impl<T: SrcSlice + ?Sized> Src<T> {
405
406 /// Constructs a new [root](crate#root) `Src` of length `0`.
407 /// Note that, because `Src`s are not growable like [`Vec`]s are, this allocation will never become larger.
408 /// Every reference to this allocation is a [root](crate#root).
409 ///
410 /// ```rust
411 /// use slice_rc::Src;
412 ///
413 /// let s = Src::<[i32]>::empty();
414 ///
415 /// assert_eq!(s.len(), 0);
416 /// ```
417 #[inline]
418 pub fn empty() -> Src<T> {
419 UniqueSrc::into_shared(UniqueSrc::empty())
420 }
421
422 /// Returns the number of elements in this `Src`.
423 /// This method deliberately shadows [`<[T]>::len`](slice::len) and [`str::len`] because this method provides a (slightly) simpler and more efficient implementation.
424 ///
425 /// This method only returns the length of the whole allocation if `self` is a [root](crate#root) `Src`.
426 ///
427 /// ```rust
428 /// use slice_rc::Src;
429 ///
430 /// let s = Src::from_array([1, 2, 3]);
431 /// assert_eq!(s.len(), 3);
432 /// ```
433 #[inline]
434 pub fn len(&self) -> usize {
435 self.len
436 }
437
438 /// Returns `true` if this `Src` has a length of `0`.
439 /// 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.
440 ///
441 /// Note that this method does not imply that this `Src` was constructed via [`Src::empty`].
442 /// Similarly, it does not imply that the entire allocation is empty, unless `self` is a [root](crate#root) `Src`.
443 ///
444 /// ```rust
445 /// use slice_rc::Src;
446 ///
447 /// let a = Src::from_array([1, 2, 3]);
448 /// assert!(!a.is_empty());
449 ///
450 /// let b = Src::<[i32]>::from_array([]);
451 /// assert!(b.is_empty());
452 /// ```
453 #[inline]
454 pub fn is_empty(&self) -> bool {
455 self.len == 0
456 }
457
458 /// Returns an `Src` pointer to an element or subslice depending on the type of index.
459 /// * If given a position (only applicable where `Self = Src<[U]>`), returns an `Src<U>` to the element at that position.
460 /// * If given a range, returns the subslice corresponding to that range.
461 ///
462 /// # Panics
463 /// If the index is in some way out of bounds, or if <code>Self = [Src]\<[str]></code> and the indices are not at [char boundaries](str::is_char_boundary).
464 ///
465 /// # Examples
466 /// ```rust
467 /// use slice_rc::Src;
468 ///
469 /// let v = Src::from_array([10, 40, 30]);
470 /// assert_eq!(Src::single(40), v.slice(1));
471 /// assert_eq!(Src::from_array([10, 40]), v.slice(0..2));
472 /// ```
473 /// Panics:
474 /// ```should_panic
475 /// # use slice_rc::Src;
476 /// let v = Src::from_array([10, 40, 30]);
477 /// let _ = v.slice(3);
478 /// let _ = v.slice(0..4);
479 /// ```
480 #[inline]
481 pub fn slice<I: SrcIndex<T>>(&self, index: I) -> Src<I::Output> {
482 index.get(self.clone())
483 }
484
485 pub(crate) fn into_item(self, index: usize) -> Src<T::Item> {
486 let header = self.header();
487 assert!(index < header.len(), "index {index} out of range for slice of length {}", header.len());
488 // SAFETY: the safety invariant of self.start implies this safety requirement, given the assertion that index <= header.len()
489 let start_ptr = unsafe { self.start.add(index) };
490 let this = Src {
491 // SAFETY: self.header has the same safety invariant as this.header
492 header: self.header,
493 // SAFETY: start_ptr was just aquired from InnerHeader::get_elem_ptr::<T::Item>(self.header, start_inc), which, with the assertions, meets the safety requirement
494 start: start_ptr,
495 // SAFETY: the assertions guarantee the safety requirements
496 len: (),
497 _phantom: PhantomData,
498 };
499 forget(self); // don't modify the strong count because this is logically the same Src
500 this
501 }
502
503 pub(crate) fn into_slice_from_bounds(self, start: Bound<usize>, end: Bound<usize>) -> Src<T> {
504 let header = self.header();
505 let start_inc = match start {
506 Bound::Excluded(val) => val + 1,
507 Bound::Included(val) => val,
508 Bound::Unbounded => 0,
509 };
510 let end_exc = match end {
511 Bound::Excluded(val) => val,
512 Bound::Included(val) => val + 1,
513 Bound::Unbounded => header.len(),
514 };
515 assert!(start_inc <= end_exc, "slice index starts at {start_inc} but ends at {end_exc}");
516 assert!(end_exc <= header.len(), "range end index {end_exc} out of range for slice of length {}", header.len());
517 T::validate_range(&self, start_inc..end_exc);
518 let len = end_exc - start_inc;
519 // SAFETY: the safety invariant of self.start implies this safety requirement, given the assertion that start_inc <= header.len()
520 let start_ptr = unsafe { self.start.add(start_inc) };
521 let this = Src {
522 // SAFETY: self.header has the same safety invariant as this.header
523 header: self.header,
524 // SAFETY: start_ptr was just aquired from InnerHeader::get_elem_ptr::<T::Item>(self.header, start_inc), which, with the assertions, meets the safety requirement
525 start: start_ptr,
526 // SAFETY: the assertions guarantee the safety requirements
527 len,
528 _phantom: PhantomData,
529 };
530 forget(self); // don't modify the strong count because this is logically the same Src
531 this
532 }
533
534}
535
536impl<T: Sized> Src<T> {
537
538 /// Constructs a new [root](crate#root) `Src` that contains only the given value.
539 ///
540 /// ```rust
541 /// use slice_rc::Src;
542 ///
543 /// let s = Src::single(42);
544 /// assert_eq!(*s, 42);
545 /// assert_eq!(Src::root(&s).len(), 1);
546 /// ```
547 #[inline]
548 pub fn single(value: T) -> Src<T> {
549 UninitSrc::single().init(value)
550 }
551
552 /// Constructs a new [root](crate#root) `Src` that contains only the value returned from the given function `f`.
553 /// The [`WeakSrc`] that `f` is given will be a weak reference to this allocation, which allows constructing a self-referential value;
554 /// it will return [`None`] from [`WeakSrc::upgrade`] until after `single_cyclic` has returned.
555 ///
556 /// This is a convienience method for a specific subset of behavior that can be obtained via [`UninitSrc`].
557 ///
558 /// ```rust
559 /// use slice_rc::{Src, WeakSrc};
560 ///
561 /// struct S {
562 /// me: WeakSrc<S>,
563 /// }
564 ///
565 /// let s = Src::single_cyclic(|me| S { me: me.clone() });
566 ///
567 /// assert!(Src::ptr_eq(&s, &s.me.upgrade().unwrap()));
568 /// ```
569 #[inline]
570 pub fn single_cyclic<F: FnOnce(&WeakSrc<T>) -> T>(f: F) -> Src<T> {
571 UniqueSrc::into_shared(UniqueSrc::single_cyclic(f))
572 }
573
574 /// Constructs a new [root](crate#root) `Src` of length `1` with uninitialized contents.
575 ///
576 /// ```rust
577 /// use slice_rc::{Src, UniqueSrc};
578 ///
579 /// let five = Src::<i32>::single_uninit();
580 ///
581 /// let mut five = Src::into_unique(five).unwrap();
582 /// five.write(5);
583 /// let five = UniqueSrc::into_shared(five);
584 ///
585 /// let five = unsafe { five.assume_init() };
586 ///
587 /// assert_eq!(*five, 5);
588 /// ```
589 #[inline]
590 pub fn single_uninit() -> Src<MaybeUninit<T>> {
591 UniqueSrc::into_shared(UniqueSrc::single_uninit())
592 }
593
594 /// Constructs a new [root](crate#root) `Src` of length `1` with uninitialized contents, with the memory being filled with `0` bytes.
595 ///
596 /// See [`MaybeUninit::zeroed`] for examples of correct and incorrect usage of this method.
597 ///
598 /// ```rust
599 /// use slice_rc::Src;
600 ///
601 /// let zero = Src::<i32>::single_zeroed();
602 /// let zero = unsafe { zero.assume_init() };
603 ///
604 /// assert_eq!(*zero, 0);
605 /// ```
606 #[inline]
607 pub fn single_zeroed() -> Src<MaybeUninit<T>> {
608 UniqueSrc::into_shared(UniqueSrc::single_zeroed())
609 }
610
611 /// Returns an `Src` equivalent to this one, but typed as a slice rather than a single element.
612 /// 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.
613 ///
614 /// ```rust
615 /// use slice_rc::Src;
616 /// use std::ptr;
617 ///
618 /// let single = Src::single(42);
619 /// let slice = Src::as_slice(&single);
620 ///
621 /// assert!(Src::ptr_eq(&single, &slice));
622 /// assert!(ptr::eq(&*single, &slice[0]));
623 /// ```
624 #[inline]
625 pub fn as_slice(this: &Src<T>) -> Src<[T]> {
626 this.header().inc_strong_count();
627 Src {
628 // SAFETY: this.header has the same invariant as this2
629 header: this.header,
630 // SAFETY: this.start has the same invariant as this2
631 start: this.start,
632 // SAFETY: this.len's invariant implies this2.len's invariant
633 len: 1,
634 _phantom: PhantomData,
635 }
636 }
637
638}
639
640impl<T> Src<[T]> {
641
642 /// Constructs a new [root](crate#root) `Src` of the given length with uninitialized contents.
643 ///
644 /// ```rust
645 /// use slice_rc::{Src, UniqueSrc};
646 ///
647 /// let fives = Src::<[i32]>::new_uninit(3);
648 ///
649 /// let mut fives = Src::into_unique(fives).unwrap();
650 /// fives[0].write(5);
651 /// fives[1].write(5);
652 /// fives[2].write(5);
653 /// let fives = UniqueSrc::into_shared(fives);
654 ///
655 /// let fives = unsafe { fives.assume_init() };
656 ///
657 /// assert_eq!(*fives, [5, 5, 5]);
658 /// ```
659 #[inline]
660 pub fn new_uninit(len: usize) -> Src<[MaybeUninit<T>]> {
661 UniqueSrc::into_shared(UniqueSrc::new_uninit(len))
662 }
663
664 /// Constructs a new [root](crate#root) `Src` of the given length with uninitialized contents, with the memory being filled with `0` bytes.
665 ///
666 /// See [`MaybeUninit::zeroed`] for examples of correct and incorrect usage of this method.
667 ///
668 /// ```rust
669 /// use slice_rc::Src;
670 ///
671 /// let zeroes = Src::<[i32]>::new_zeroed(3);
672 /// let zeroes = unsafe { zeroes.assume_init() };
673 ///
674 /// assert_eq!(*zeroes, [0, 0, 0]);
675 /// ```
676 #[inline]
677 pub fn new_zeroed(len: usize) -> Src<[MaybeUninit<T>]> {
678 UniqueSrc::into_shared(UniqueSrc::new_zeroed(len))
679 }
680
681 /// Constructs a new [root](crate#root) `Src` of the given length where each element is produced by calling `f` with that element's index while walking forward through the slice.
682 ///
683 /// This essentially the same as writing
684 /// ```text
685 /// Src::from_array([f(0), f(1), f(2), ..., f(len - 2), f(len - 1)])
686 /// ```
687 /// and is similar to `(0..len).map(f)`, just for `Src`s rather than iterators.
688 ///
689 /// If `len == 0`, this produces an empty `Src` without ever calling `f`.
690 ///
691 /// ```rust
692 /// use slice_rc::Src;
693 ///
694 /// let slice = Src::from_fn(5, |i| i);
695 /// assert_eq!(*slice, [0, 1, 2, 3, 4]);
696 ///
697 /// let slice2 = Src::from_fn(8, |i| i * 2);
698 /// assert_eq!(*slice2, [0, 2, 4, 6, 8, 10, 12, 14]);
699 ///
700 /// let bool_slice = Src::from_fn(5, |i| i % 2 == 0);
701 /// assert_eq!(*bool_slice, [true, false, true, false, true]);
702 /// ```
703 ///
704 /// You can also capture things, so you can use closures with mutable state.
705 /// The slice is generated in ascending index order, starting from the front and going towards the back.
706 /// ```rust
707 /// # use slice_rc::Src;
708 /// let mut state = 1;
709 /// let s = Src::from_fn(6, |_| { let x = state; state *= 2; x });
710 /// assert_eq!(*s, [1, 2, 4, 8, 16, 32]);
711 /// ```
712 ///
713 /// # Panics
714 ///
715 /// Panics if `f` panics; in this event, any elements that have been initialized will be properly dropped.
716 /// ```rust
717 /// # use slice_rc::Src;
718 /// # use std::cell::Cell;
719 /// thread_local! {
720 /// static DROPPED: Cell<usize> = Cell::new(0);
721 /// }
722 ///
723 /// struct Droppable;
724 ///
725 /// impl Drop for Droppable {
726 /// fn drop(&mut self) {
727 /// DROPPED.with(|dropped| dropped.update(|x| x + 1));
728 /// }
729 /// }
730 ///
731 /// let _ = std::panic::catch_unwind(|| {
732 /// Src::from_fn(10, |i| {
733 /// if i >= 5 { panic!() }
734 /// Droppable
735 /// })
736 /// });
737 ///
738 /// assert_eq!(DROPPED.get(), 5);
739 /// ```
740 #[inline]
741 pub fn from_fn<F: FnMut(usize) -> T>(len: usize, f: F) -> Src<[T]> {
742 UninitSrc::new(len).init_from_fn(f)
743 }
744
745 /// Constructs a new [root](crate#root) `Src` 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.
746 ///
747 /// This method is like [`Src::from_fn`], but in this the function `f` is passed a root [`WeakSrc`] pointer to the allocation to allow constructing self-referential elements.
748 ///
749 /// This is a convienience method for a specific subset of behavior that can be obtained via [`UninitSrc`].
750 ///
751 /// ```rust
752 /// use slice_rc::{Src, WeakSrc};
753 ///
754 /// struct S {
755 /// val: usize,
756 /// root: WeakSrc<[S]>,
757 /// }
758 ///
759 /// let root = Src::cyclic_from_fn(5, |root, i| S {
760 /// val: i * 2,
761 /// root: root.clone(),
762 /// });
763 ///
764 /// assert_eq!(root.iter().map(|s| s.val).collect::<Vec<_>>(), vec![0, 2, 4, 6, 8]);
765 /// assert!(root.iter().all(|s| Src::ptr_eq(&root, &s.root.upgrade().unwrap())));
766 /// ```
767 ///
768 /// It is possible to obtain a `WeakSrc` to the individual element that is being initialized via [`WeakSrc::slice`]:
769 ///
770 /// ```rust
771 /// # use slice_rc::{Src, WeakSrc};
772 /// struct S {
773 /// val: usize,
774 /// me: WeakSrc<S>,
775 /// }
776 ///
777 /// let root = Src::cyclic_from_fn(5, |root, i| S {
778 /// val: i * 2,
779 /// me: root.slice(i),
780 /// });
781 ///
782 /// assert!(root.iter().enumerate().all(|(i, s)| Src::ptr_eq(&root.slice(i), &s.me.upgrade().unwrap())));
783 /// ```
784 pub fn cyclic_from_fn<F: FnMut(&WeakSrc<[T]>, usize) -> T>(len: usize, mut f: F) -> Src<[T]> {
785 let this = UninitSrc::new(len);
786 let weak = this.downgrade();
787 this.init_from_fn(|i| f(&weak, i))
788 }
789
790 /// Constructs a new [root](crate#root) `Src` from the given iterator.
791 ///
792 /// This method is essentially shorthand for
793 /// ```rust
794 /// use slice_rc::Src;
795 ///
796 /// # fn f<T>(iter: impl IntoIterator<Item = T, IntoIter: std::iter::ExactSizeIterator>) -> Src<[T]> {
797 /// let mut iter = iter.into_iter();
798 /// Src::from_fn(iter.len(), |_| iter.next().unwrap())
799 /// # }
800 /// ```
801 ///
802 /// The iterator must be [`ExactSizeIterator`] because `Src`s cannot be resized,
803 /// so the number of elements must be known at allocation-time, i.e., before any of the elements are initialized.
804 /// If you want to use a non-[`ExactSizeIterator`], use <code>iter.[collect](Iterator::collect)::\<[Vec]\<_>>()</code>.
805 pub fn from_iter<I: IntoIterator<Item = T, IntoIter: ExactSizeIterator>>(iter: I) -> Src<[T]> {
806 let mut iter = iter.into_iter();
807 Self::from_fn(iter.len(), |_| iter.next().unwrap())
808 }
809
810 /// Constructs a new [root](crate#root) `Src` from the given array.
811 ///
812 /// This method is effectively equivalent to passing an array to [`Src::from_iter`], but it is more efficient.
813 /// As such, it is effectively shorthand for <code>Src::[from_fn](N, |i| values\[i])</code>, but again, more efficient
814 /// (though not by enough to make <code>Src::from_array([array::from_fn]::<_, N, _>(f))</code> any better than <code>Src::[from_fn](N, f)</code>).
815 ///
816 /// Note that the my assertions about efficiency are not based any kind of benchmarking,
817 /// just the fact that this method uses a single [`ptr::write`] where [`Src::from_fn`] and [`Src::from_iter`] use `N` arbitrary function calls and `N` [`ptr::write`]s.
818 /// As <code>[array::from_fn]</code> re-introduces at least the `N` arbitrary function calls, its difference (again, without benchmarking) is negligible.
819 ///
820 /// [from_fn]: Src::from_fn
821 /// [`ptr::write`]: std::ptr::write
822 /// [array::from_fn]: std::array::from_fn
823 #[inline]
824 pub fn from_array<const N: usize>(values: [T; N]) -> Src<[T]> {
825 UniqueSrc::into_shared(UniqueSrc::from_array(values))
826 }
827
828 /// Constructs a new [root](crate#root) `Src` of the given length where each element is the type's [default](Default::default).
829 ///
830 /// This method is essentially equivalent to <code>Src::[from_fn](Src::from_fn)(len, |_| [Default::default]\())</code>.
831 #[inline]
832 pub fn from_default(len: usize) -> Src<[T]> where T: Default {
833 Self::from_fn(len, |_| Default::default())
834 }
835
836 /// Constructs a new [root](crate#root) `Src` of the given length where each element is a clone of `value`.
837 ///
838 /// This method is essentially equivalent to <code>Src::[from_fn](Src::from_fn)(len, |_| value.[clone](Clone::clone)())</code>.
839 #[inline]
840 pub fn filled(len: usize, value: &T) -> Src<[T]> where T: Clone {
841 Self::from_fn(len, |_| value.clone())
842 }
843
844 /// Constructs a new [root](crate#root) `Src` of the given length where each element is a clone of the value returned from `f`.
845 /// `f` is passed a root [`WeakSrc`] pointer to the allocation; this can be used to make self-referential structures.
846 ///
847 /// ```rust
848 /// use slice_rc::{Src, WeakSrc};
849 ///
850 /// #[derive(Clone)]
851 /// struct S {
852 /// val: i32,
853 /// root: WeakSrc<[S]>,
854 /// }
855 ///
856 /// let root = Src::filled_cyclic(5, |root| S { val: 42, root: root.clone() });
857 /// assert!(root.iter().all(|s| s.val == 42));
858 /// assert!(root.iter().all(|s| Src::ptr_eq(&root, &s.root.upgrade().unwrap())));
859 /// ```
860 #[inline]
861 pub fn filled_cyclic<F: FnOnce(&WeakSrc<[T]>) -> T>(len: usize, f: F) -> Src<[T]> where T: Clone {
862 UniqueSrc::into_shared(UniqueSrc::filled_cyclic(len, f))
863 }
864
865 /// Constructs a new [root](crate#root) `Src` as a clone of the given slice.
866 ///
867 /// This method is essentially shorthand for <code>Src::[from_fn](Src::from_fn)(values.[len](slice::len)(), |i| values\[i].clone())</code>,
868 /// but without the implicit bounds checking for slice indexing.
869 #[inline]
870 pub fn cloned(values: &[T]) -> Src<[T]> where T: Clone {
871 UniqueSrc::into_shared(UniqueSrc::cloned(values))
872 }
873
874 /// Constructs a new [root](crate#root) `Src` as a copy of the given slice.
875 ///
876 /// This method is functionally shorthand for <code>Src::[from_fn](Src::from_fn)(values.[len](slice::len)(), |i| values\[i])</code>,
877 /// but without the implicit bounds checking for slice indexing.
878 ///
879 /// This method is fairly efficient, as it is basically just an allocation (requisite for any `Src` constructor) and a [`memcpy`](std::ptr::copy_nonoverlapping).
880 #[inline]
881 pub fn copied(values: &[T]) -> Src<[T]> where T: Copy {
882 UniqueSrc::into_shared(UniqueSrc::copied(values))
883 }
884
885}
886
887impl<T> Src<MaybeUninit<T>> {
888
889 /// Converts to `Src<T>`.
890 ///
891 /// # Safety
892 ///
893 /// As with [`MaybeUninit::assume_init`], it is up to the caller to guarantee that the inner value really is in an initialized state.
894 /// Calling this when the content is not yet fully initialized causes immediate undefined behavior.
895 ///
896 /// # Examples
897 ///
898 /// ```rust
899 /// use slice_rc::Src;
900 ///
901 /// let zero = Src::<i32>::single_zeroed();
902 /// let zero = unsafe { zero.assume_init() };
903 ///
904 /// assert_eq!(*zero, 0);
905 /// ```
906 pub unsafe fn assume_init(self) -> Src<T> {
907 // TODO: rephrase the safety requirements for InnerHeader to explicitly allow punning between T and type with T-like layout
908 let this = Src {
909 // 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
910 header: self.header,
911 // 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
912 start: self.start.cast(),
913 // 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
914 len: self.len,
915 _phantom: PhantomData,
916 };
917 forget(self); // don't decrease the strong counter because this is logically the same Src
918 this
919 }
920
921}
922
923impl<T> Src<[MaybeUninit<T>]> {
924
925 /// Converts to `Src<[T]>`.
926 ///
927 /// # Safety
928 ///
929 /// As with [`MaybeUninit::assume_init`], it is up to the caller to guarantee that the inner value really is in an initialized state.
930 /// Calling this when the content is not yet fully initialized causes immediate undefined behavior.
931 ///
932 /// # Examples
933 ///
934 /// ```rust
935 /// use slice_rc::Src;
936 ///
937 /// let zeroes = Src::<[i32]>::new_zeroed(3);
938 /// let zeroes = unsafe { zeroes.assume_init() };
939 ///
940 /// assert_eq!(*zeroes, [0, 0, 0]);
941 /// ```
942 pub unsafe fn assume_init(self) -> Src<[T]> {
943 // TODO: rephrase the safety requirements for InnerHeader to explicitly allow punning between T and type with T-like layout
944 let this = Src {
945 // 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
946 header: self.header,
947 // 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
948 start: self.start.cast(),
949 // 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
950 len: self.len,
951 _phantom: PhantomData,
952 };
953 forget(self); // don't decrease the strong counter because this is logically the same Src
954 this
955 }
956
957}
958
959impl Src<str> {
960
961 /// Constructs a new [`root`](crate#root) `Src` as a copy of the given string.
962 ///
963 /// ```rust
964 /// use slice_rc::Src;
965 ///
966 /// let hello = Src::new("Hello World!");
967 ///
968 /// assert_eq!(&*hello, "Hello World!");
969 /// ```
970 #[inline]
971 pub fn new(s: impl AsRef<str>) -> Src<str> {
972 UniqueSrc::into_shared(UniqueSrc::new(s))
973 }
974
975 /// Converts an `Src` of bytes to a string `Src`.
976 ///
977 /// [`str`] and [`[u8]`](slice) are both slices of bytes, so this function converts between the two.
978 /// Not all byte slices are valid string slices, however: [`str`] must be valid UTF-8.
979 /// This method checks to ensure that the bytes are valid UTF-8, and then does the conversion.
980 ///
981 /// 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,
982 /// there is an unsafe version of this method, [`from_utf8_unchecked`](Src::from_utf8_unchecked),
983 /// which has the same behavior but skips the check.
984 ///
985 /// # Errors
986 ///
987 /// Returns `Err` if the slice is not UTF-8 with a description as to why the provided slice is not UTF-8.
988 ///
989 /// # Examples
990 ///
991 /// Basic usage:
992 ///
993 /// ```rust
994 /// use slice_rc::Src;
995 ///
996 /// let sparkle_heart = Src::from_array([240, 159, 146, 150]);
997 ///
998 /// let sparkle_heart = Src::from_utf8(sparkle_heart)?;
999 ///
1000 /// assert_eq!("💖", &*sparkle_heart);
1001 /// # Ok::<_, std::str::Utf8Error>(())
1002 /// ```
1003 ///
1004 /// Incorrect bytes:
1005 ///
1006 /// ```rust
1007 /// # use slice_rc::Src;
1008 /// let sparkle_heart = Src::from_array([0, 159, 146, 150]);
1009 ///
1010 /// assert!(Src::from_utf8(sparkle_heart).is_err());
1011 /// ```
1012 #[inline]
1013 pub fn from_utf8(v: Src<[u8]>) -> Result<Src<str>, Utf8Error> {
1014 let _: &str = str::from_utf8(&*v)?;
1015 // SAFETY: <str>::from_utf8() guarantees that the contents are UTF-8
1016 Ok(unsafe { Src::from_utf8_unchecked(v) })
1017 }
1018
1019 /// Converts an `Src` of bytes to a string `Src` without checking that the string contains valid UTF-8.
1020 ///
1021 /// See the safe version, [`from_utf8`](Src::from_utf8), for more information.
1022 ///
1023 /// # Safety
1024 ///
1025 /// The bytes passed in must be valid UTF-8.
1026 ///
1027 /// # Examples
1028 ///
1029 /// ```rust
1030 /// use slice_rc::Src;
1031 ///
1032 /// let sparkle_heart = Src::from_array([240, 159, 146, 150]);
1033 ///
1034 /// let sparkle_heart = unsafe { Src::from_utf8_unchecked(sparkle_heart) };
1035 ///
1036 /// assert_eq!("💖", &*sparkle_heart);
1037 /// ```
1038 #[inline]
1039 pub unsafe fn from_utf8_unchecked(v: Src<[u8]>) -> Src<str> {
1040 // TODO: rephrase the safety requirements for InnerHeader to explicitly allow punning between T and type with T-like layout
1041 let this = Src {
1042 // SAFETY: v.header has *almost* the same safety invariant as this.header: the only difference is that v uses [u8] where this expects str;
1043 // 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
1044 header: v.header,
1045 // SAFETY: v.start has *almost* the same safety invariant as this.start: the only difference is that v uses [u8] where this expects str;
1046 // 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
1047 start: v.start,
1048 // SAFETY: v.len has *almost* the same safety invariant as this.len: the only difference is that v uses [u8] where this expects str;
1049 // 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
1050 len: v.len,
1051 _phantom: PhantomData,
1052 };
1053 forget(v);
1054 this
1055 }
1056
1057 /// Converts a string `Src` to a `Src` of bytes.
1058 /// To convert the the bytes back to a string, use the [`from_utf8`](Src::from_utf8) method.
1059 ///
1060 /// # Examples
1061 ///
1062 /// ```rust
1063 /// use slice_rc::Src;
1064 ///
1065 /// let bytes = Src::as_bytes(&Src::new("bors"));
1066 /// assert_eq!(b"bors", &*bytes);
1067 /// ```
1068 #[inline]
1069 pub fn as_bytes(this: &Src<str>) -> Src<[u8]> {
1070 this.header().inc_strong_count();
1071 // TODO: rephrase the safety requirements for InnerHeader to explicitly allow punning between T and type with T-like layout
1072 Src {
1073 // SAFETY: this.header has *almost* the same safety invariant as this2.header: the only difference is that this uses str where this2 expects [u8];
1074 // the pun from str to [u8] relaxes the safety requirement that this's content is valid UTF-8
1075 header: this.header,
1076 // SAFETY: this.start has *almost* the same safety invariant as this2.start: the only difference is that this uses str where this2 expects [u8];
1077 // the pun from str to [u8] relaxes the safety requirement that this's content is valid UTF-8
1078 start: this.start,
1079 // SAFETY: this.len has *almost* the same safety invariant as this2.len: the only difference is that this uses str where this2 expects [u8];
1080 // the pun from str to [u8] relaxes the safety requirement that this's content is valid UTF-8
1081 len: this.len,
1082 _phantom: PhantomData,
1083 }
1084 }
1085
1086}
1087
1088impl<T: SrcTarget + ?Sized> Clone for Src<T> {
1089
1090 #[inline]
1091 fn clone(&self) -> Self {
1092 self.header().inc_strong_count();
1093 Self {
1094 // SAFETY: this.header has the same safety invariant as _.header
1095 header: self.header,
1096 // SAFETY: this.start has the same safety invariant as _.start
1097 start: self.start,
1098 // SAFETY: this.len has the same safety invariant as _.len
1099 len: self.len,
1100 _phantom: PhantomData,
1101 }
1102 }
1103
1104}
1105
1106impl<T: Default> Default for Src<T> {
1107
1108 #[inline]
1109 fn default() -> Self {
1110 Self::single(T::default())
1111 }
1112
1113}
1114
1115impl<T: SrcTarget + ?Sized> Deref for Src<T> {
1116
1117 type Target = T;
1118
1119 #[inline]
1120 fn deref(&self) -> &Self::Target {
1121 T::get(self)
1122 }
1123
1124}
1125
1126impl<T: SrcTarget + ?Sized> Borrow<T> for Src<T> {
1127
1128 #[inline]
1129 fn borrow(&self) -> &T {
1130 &**self
1131 }
1132
1133}
1134
1135impl<T: SrcTarget + ?Sized> AsRef<T> for Src<T> {
1136
1137 #[inline]
1138 fn as_ref(&self) -> &T {
1139 &**self
1140 }
1141
1142}
1143
1144impl<T: SrcTarget + Index<I> + ?Sized, I> Index<I> for Src<T> {
1145
1146 type Output = T::Output;
1147
1148 #[inline]
1149 fn index(&self, index: I) -> &Self::Output {
1150 &self.deref()[index]
1151 }
1152
1153}
1154
1155impl<T: Hash + SrcTarget + ?Sized> Hash for Src<T> {
1156
1157 #[inline]
1158 fn hash<H: Hasher>(&self, state: &mut H) {
1159 T::hash(&**self, state);
1160 }
1161
1162}
1163
1164impl<T: PartialEq<U> + SrcTarget + ?Sized, U: SrcTarget + ?Sized> PartialEq<Src<U>> for Src<T> {
1165
1166 #[inline]
1167 fn eq(&self, other: &Src<U>) -> bool {
1168 T::eq(&**self, &**other)
1169 }
1170
1171 #[inline]
1172 fn ne(&self, other: &Src<U>) -> bool {
1173 T::ne(&**self, &**other)
1174 }
1175
1176}
1177
1178impl<T: Eq + SrcTarget + ?Sized> Eq for Src<T> {}
1179
1180impl<T: PartialOrd<U> + SrcTarget + ?Sized, U: SrcTarget + ?Sized> PartialOrd<Src<U>> for Src<T> {
1181
1182 #[inline]
1183 fn ge(&self, other: &Src<U>) -> bool {
1184 T::ge(&**self, &**other)
1185 }
1186
1187 #[inline]
1188 fn gt(&self, other: &Src<U>) -> bool {
1189 T::gt(&**self, &**other)
1190 }
1191
1192 #[inline]
1193 fn le(&self, other: &Src<U>) -> bool {
1194 T::le(&**self, &**other)
1195 }
1196
1197 #[inline]
1198 fn lt(&self, other: &Src<U>) -> bool {
1199 T::lt(&**self, &**other)
1200 }
1201
1202 #[inline]
1203 fn partial_cmp(&self, other: &Src<U>) -> Option<Ordering> {
1204 T::partial_cmp(&**self, &**other)
1205 }
1206
1207}
1208
1209impl<T: Ord + SrcTarget + ?Sized> Ord for Src<T> {
1210
1211 #[inline]
1212 fn cmp(&self, other: &Self) -> Ordering {
1213 T::cmp(&**self, &**other)
1214 }
1215
1216}
1217
1218impl<T: Debug + SrcTarget + ?Sized> Debug for Src<T> {
1219
1220 #[inline]
1221 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1222 T::fmt(self, f)
1223 }
1224
1225}
1226
1227impl<T: SrcTarget + ?Sized> Pointer for Src<T> {
1228
1229 #[inline]
1230 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1231 Pointer::fmt(&self.start, f)
1232 }
1233
1234}
1235
1236impl<T: SrcTarget + ?Sized> Drop for Src<T> {
1237
1238 fn drop(&mut self) {
1239 // SAFETY:
1240 // * all constructor fns for Src initialize header from InnerHeader::new_inner::<T::Item>
1241 // * all constructor fns for Src initialize the elements
1242 // * the header is only accessed from InnerHeader::get_header
1243 // * this is one of two callsites for InnerHeader::drop_strong::<T::Item>, the other being UniqueSrc::drop;
1244 // as a UniqueSrc cannot co-exist (for the same allocation) with an Src, this will be the last strong reference iff this is the last Src with access to this allocation's body
1245 unsafe { InnerHeader::drop_strong::<T::Item>(self.header); }
1246 }
1247
1248}
1249
1250#[cfg(test)]
1251mod tests {
1252
1253 use std::{cell::Cell, mem::MaybeUninit, ops::Deref, panic::{catch_unwind, AssertUnwindSafe}, str::Utf8Error};
1254
1255 use crate::*;
1256
1257 #[test]
1258 fn ptr_eq() {
1259 let s1: Src<[u8]> = Src::from_default(0);
1260 let s2: Src<[u8]> = Src::clone(&s1);
1261 assert_eq!(s1, s2);
1262 assert!(Src::ptr_eq(&s1, &s2));
1263 let s3: Src<[u8]> = Src::from_default(0);
1264 assert_eq!(s1, s3);
1265 assert_eq!(s2, s3);
1266 assert!(!Src::ptr_eq(&s1, &s3));
1267 assert!(!Src::ptr_eq(&s2, &s3));
1268 }
1269
1270 #[test]
1271 fn same_root() {
1272 let s1: Src<[u8]> = Src::from_default(1);
1273 let s2: Src<[u8]> = s1.slice(1..);
1274 assert_ne!(s1, s2);
1275 assert!(!Src::ptr_eq(&s1, &s2));
1276 assert!(Src::same_root(&s1, &s2));
1277 let s3: Src<[u8]> = Src::from_default(1);
1278 let s4: Src<[u8]> = s3.slice(1..);
1279 assert_eq!(s1, s3);
1280 assert_ne!(s3, s4);
1281 assert_eq!(s2, s4);
1282 assert!(!Src::ptr_eq(&s1, &s3));
1283 assert!(!Src::ptr_eq(&s2, &s4));
1284 assert!(!Src::ptr_eq(&s2, &s4));
1285 assert!(!Src::same_root(&s1, &s3));
1286 assert!(!Src::same_root(&s2, &s4));
1287 assert!(Src::same_root(&s3, &s4));
1288 }
1289
1290 #[test]
1291 fn is_root() {
1292 let s1: Src<[u8]> = Src::from_default(1);
1293 let s2: Src<[u8]> = s1.slice(..);
1294 let s3: Src<[u8]> = s1.slice(1..);
1295 assert!(Src::is_root(&s1));
1296 assert!(Src::is_root(&s2));
1297 assert!(!Src::is_root(&s3));
1298 }
1299
1300 #[test]
1301 fn downgrade() {
1302 let s1: Src<[u8]> = Src::from_default(0);
1303 let w: WeakSrc<[u8]> = Src::downgrade(&s1);
1304 let s2: Src<[u8]> = w.upgrade().unwrap();
1305 assert_eq!(s1, s2);
1306 }
1307
1308 #[test]
1309 fn strong_count() {
1310 let s1: Src<[u8]> = Src::from_default(0);
1311 assert_eq!(Src::strong_count(&s1), 1);
1312 let s2: Src<[u8]> = Src::clone(&s1);
1313 assert_eq!(Src::strong_count(&s1), 2);
1314 assert_eq!(Src::strong_count(&s2), 2);
1315 let w1: WeakSrc<[u8]> = Src::downgrade(&s1);
1316 assert_eq!(Src::strong_count(&s1), 2);
1317 assert_eq!(Src::strong_count(&s2), 2);
1318 assert_eq!(w1.strong_count(), 2);
1319 let w2: WeakSrc<[u8]> = Src::downgrade(&s1);
1320 assert_eq!(Src::strong_count(&s1), 2);
1321 assert_eq!(Src::strong_count(&s2), 2);
1322 assert_eq!(w1.strong_count(), 2);
1323 assert_eq!(w2.strong_count(), 2);
1324 std::mem::drop(s1);
1325 assert_eq!(Src::strong_count(&s2), 1);
1326 assert_eq!(w1.strong_count(), 1);
1327 assert_eq!(w2.strong_count(), 1);
1328 std::mem::drop(s2);
1329 assert_eq!(w1.strong_count(), 0);
1330 assert_eq!(w2.strong_count(), 0);
1331 }
1332
1333 #[test]
1334 fn weak_count() {
1335 let s1: Src<[u8]> = Src::from_default(0);
1336 assert_eq!(Src::weak_count(&s1), 0);
1337 let s2: Src<[u8]> = Src::clone(&s1);
1338 assert_eq!(Src::weak_count(&s1), 0);
1339 assert_eq!(Src::weak_count(&s2), 0);
1340 let w1: WeakSrc<[u8]> = Src::downgrade(&s1);
1341 assert_eq!(Src::weak_count(&s1), 1);
1342 assert_eq!(Src::weak_count(&s2), 1);
1343 assert_eq!(w1.weak_count(), 1);
1344 let w2: WeakSrc<[u8]> = w1.clone();
1345 assert_eq!(Src::weak_count(&s1), 2);
1346 assert_eq!(Src::weak_count(&s2), 2);
1347 assert_eq!(w1.weak_count(), 2);
1348 assert_eq!(w2.weak_count(), 2);
1349 std::mem::drop(s1);
1350 assert_eq!(Src::weak_count(&s2), 2);
1351 assert_eq!(w1.weak_count(), 2);
1352 assert_eq!(w2.weak_count(), 2);
1353 std::mem::drop(w1);
1354 assert_eq!(Src::weak_count(&s2), 1);
1355 assert_eq!(w2.weak_count(), 1);
1356 std::mem::drop(s2);
1357 assert_eq!(w2.weak_count(), 0);
1358 }
1359
1360 #[test]
1361 fn into_unique() {
1362 let s1: Src<[u8]> = Src::from_default(0);
1363 let s2: Src<[u8]> = Src::clone(&s1);
1364 let s1: Src<[u8]> = Src::into_unique(s1).unwrap_err();
1365 std::mem::drop(s2);
1366 let w: WeakSrc<[u8]> = Src::downgrade(&s1);
1367 assert!(w.upgrade().is_some());
1368 let u: UniqueSrc<[u8]> = Src::into_unique(s1).unwrap();
1369 assert!(w.upgrade().is_none());
1370 let s1: Src<[u8]> = UniqueSrc::into_shared(u);
1371 assert!(w.upgrade().is_some());
1372 _ = s1;
1373 }
1374
1375 #[test]
1376 fn make_unique() {
1377 { // non-unique
1378 let s1: Src<[u8]> = Src::from_default(0);
1379 let s2: Src<[u8]> = Src::clone(&s1);
1380 let w1: WeakSrc<[u8]> = Src::downgrade(&s1);
1381 let u: UniqueSrc<[u8]> = Src::make_unique(s1);
1382 let w2: WeakSrc<[u8]> = UniqueSrc::downgrade(&u);
1383 assert!(!w1.same_root(&w2));
1384 _ = s2;
1385 }
1386 { // unique
1387 let s: Src<[u8]> = Src::from_default(0);
1388 let w1: WeakSrc<[u8]> = Src::downgrade(&s);
1389 let u: UniqueSrc<[u8]> = Src::make_unique(s);
1390 let w2: WeakSrc<[u8]> = UniqueSrc::downgrade(&u);
1391 assert!(w1.same_root(&w2));
1392 }
1393 }
1394
1395 #[test]
1396 fn empty() {
1397 let s: Src<[u8]> = Src::empty();
1398 assert!(s.is_empty());
1399 assert_eq!(s.len(), 0);
1400 let s: Src<str> = Src::empty();
1401 assert!(s.is_empty());
1402 assert_eq!(s.len(), 0);
1403 }
1404
1405 #[test]
1406 fn len() {
1407 let s: Src<[u8]> = Src::from_default(0);
1408 assert_eq!(s.len(), 0);
1409 let s: Src<[u8]> = Src::from_default(1);
1410 assert_eq!(s.len(), 1);
1411 let s: Src<[u8]> = Src::from_default(17);
1412 assert_eq!(s.len(), 17);
1413 let s: Src<[u8]> = s.slice(3..14);
1414 assert_eq!(s.len(), 11);
1415 let s: Src<[u8]> = s.slice(3..3);
1416 assert_eq!(s.len(), 0);
1417 }
1418
1419 #[test]
1420 fn is_empty() {
1421 let s: Src<[u8]> = Src::from_default(0);
1422 assert!(s.is_empty());
1423 let s: Src<[u8]> = Src::from_default(1);
1424 assert!(!s.is_empty());
1425 let s: Src<[u8]> = Src::from_default(17);
1426 assert!(!s.is_empty());
1427 let s: Src<[u8]> = s.slice(3..14);
1428 assert!(!s.is_empty());
1429 let s: Src<[u8]> = s.slice(3..3);
1430 assert!(s.is_empty());
1431 }
1432
1433 #[test]
1434 fn root() {
1435 let s1: Src<[u8]> = Src::from_default(1);
1436 assert!(Src::is_root(&s1));
1437 let s1: Src<[u8]> = s1.slice(1..);
1438 assert!(!Src::is_root(&s1));
1439 let s2: Src<[u8]> = Src::root(&s1);
1440 assert!(Src::is_root(&s2));
1441 assert!(Src::same_root(&s1, &s2));
1442 }
1443
1444 #[test]
1445 fn slice() {
1446 { // slice
1447 let s1: Src<[u8]> = Src::from_array([1, 2, 3]);
1448 assert_eq!(&*s1, &[1, 2, 3]);
1449 let s1: Src<[u8]> = s1.slice(1..);
1450 assert_eq!(&*s1, &[2, 3]);
1451 let s2: Src<[u8]> = s1.slice(..1);
1452 assert_eq!(&*s2, &[2]);
1453 assert!(Src::same_root(&s1, &s2));
1454 }
1455 { // item 1
1456 let s1: Src<[u8]> = Src::from_array([1, 2, 3]);
1457 assert_eq!(&*s1, &[1, 2, 3]);
1458 let s2: Src<u8> = s1.slice(2);
1459 assert_eq!(&*s2, &3);
1460 let s2: Src<[u8]> = Src::as_slice(&s2);
1461 assert_eq!(&*s2, &[3]);
1462 assert!(Src::same_root(&s1, &s2));
1463 }
1464 { // item 2
1465 let s1: Src<[u8]> = Src::from_array([1, 2, 3]);
1466 assert_eq!(&*s1, &[1, 2, 3]);
1467 let s1: Src<[u8]> = s1.slice(1..);
1468 assert_eq!(&*s1, &[2, 3]);
1469 let s2: Src<u8> = s1.slice(0);
1470 assert_eq!(&*s2, &2);
1471 let s2: Src<[u8]> = Src::as_slice(&s2);
1472 assert_eq!(&*s2, &[2]);
1473 assert!(Src::same_root(&s1, &s2));
1474 }
1475 }
1476
1477 #[test]
1478 fn single() {
1479 let s: Src<u8> = Src::single(42);
1480 assert_eq!(*s, 42);
1481 }
1482
1483 #[test]
1484 fn single_cyclic() {
1485 { // non-cyclic
1486 let s: Src<u8> = Src::single_cyclic(|_| 42);
1487 assert_eq!(*s, 42);
1488 }
1489 { // cyclic
1490 struct S {
1491
1492 this: WeakSrc<S>,
1493 i: usize,
1494
1495 }
1496 let s: Src<S> = Src::single_cyclic(|weak| S { this: weak.clone(), i: 42 });
1497 assert_eq!(s.i, 42);
1498 let w: WeakSrc<S> = Src::downgrade(&s);
1499 assert!(WeakSrc::ptr_eq(&s.this, &w));
1500 }
1501 }
1502
1503 #[test]
1504 fn single_uninit() {
1505 let s: Src<MaybeUninit<u8>> = Src::single_uninit();
1506 let mut u: UniqueSrc<MaybeUninit<u8>> = Src::make_unique(s);
1507 u.write(42);
1508 let s: Src<MaybeUninit<u8>> = UniqueSrc::into_shared(u);
1509 // SAFETY: just initialized it with u.write()
1510 let s: Src<u8> = unsafe { s.assume_init() };
1511 assert_eq!(*s, 42);
1512 }
1513
1514 #[test]
1515 fn single_zeroed() {
1516 let s: Src<MaybeUninit<u8>> = Src::single_zeroed();
1517 // SAFETY: u8 is a zeroable type
1518 let s: Src<u8> = unsafe { s.assume_init() };
1519 assert_eq!(*s, 0);
1520 }
1521
1522 #[test]
1523 fn as_slice() {
1524 { // single root
1525 let s1: Src<u8> = Src::single(42);
1526 let s2: Src<[u8]> = Src::as_slice(&s1);
1527 assert_eq!([*s1], *s2);
1528 }
1529 { // from slice
1530 let s1: Src<[u8]> = Src::from_array([1, 2, 3]);
1531 let s2: Src<u8> = s1.slice(1);
1532 let s3: Src<[u8]> = Src::as_slice(&s2);
1533 assert_eq!(s1[1], *s2);
1534 assert_eq!([*s2], *s3);
1535 }
1536 }
1537
1538 #[test]
1539 fn new_uninit() {
1540 let s: Src<[MaybeUninit<u8>]> = Src::new_uninit(3);
1541 assert_eq!(s.len(), 3);
1542 let mut u: UniqueSrc<[MaybeUninit<u8>]> = Src::make_unique(s);
1543 for (i, elem) in u.iter_mut().enumerate() {
1544 elem.write(i as _);
1545 }
1546 let s: Src<[MaybeUninit<u8>]> = UniqueSrc::into_shared(u);
1547 // SAFETY: just initialized it with all the elem.write()s
1548 let s: Src<[u8]> = unsafe { s.assume_init() };
1549 assert_eq!(*s, [0, 1, 2]);
1550 }
1551
1552 #[test]
1553 fn new_zeroed() {
1554 let s: Src<[MaybeUninit<u8>]> = Src::new_zeroed(3);
1555 assert_eq!(s.len(), 3);
1556 // SAFETY: u8 is a zeroable type
1557 let s: Src<[u8]> = unsafe { s.assume_init() };
1558 assert_eq!(*s, [0, 0, 0]);
1559 }
1560
1561 #[test]
1562 fn from_fn() {
1563 { // normal
1564 let s: Src<[usize]> = Src::from_fn(3, |i| i * 2);
1565 assert_eq!(*s, [0, 2, 4]);
1566 }
1567 { // panic
1568 let drop_flags: [_; 6] = std::array::from_fn(|_| AssertUnwindSafe(Cell::new(false)));
1569 struct DropFlagger<'a>(&'a Cell<bool>);
1570 impl Drop for DropFlagger<'_> {
1571
1572 fn drop(&mut self) {
1573 self.0.update(|v| !v)
1574 }
1575
1576 }
1577 let _: Result<_, _> = catch_unwind(|| {
1578 let _: Src<[DropFlagger<'_>]> = Src::from_fn(drop_flags.len(), |i| {
1579 if i >= 3 { panic!() }
1580 DropFlagger(&drop_flags[i])
1581 });
1582 });
1583 assert!(drop_flags[..3].iter().map(Deref::deref).all(Cell::get));
1584 assert!(!drop_flags[3..].iter().map(Deref::deref).any(Cell::get));
1585 }
1586 }
1587
1588 #[test]
1589 fn cyclic_from_fn() {
1590 { // normal, not cyclic
1591 let s: Src<[usize]> = Src::cyclic_from_fn(3, |_, i| i * 2);
1592 assert_eq!(*s, [0, 2, 4]);
1593 }
1594 { // normal, cyclic
1595 struct S {
1596
1597 all: WeakSrc<[S]>,
1598 i: usize,
1599
1600 }
1601 let s1: Src<[S]> = Src::cyclic_from_fn(3, |w, i| S { all: w.clone(), i: i * 2 });
1602 assert_eq!(s1[0].i, 0);
1603 assert_eq!(s1[1].i, 2);
1604 assert_eq!(s1[2].i, 4);
1605 let s2: Src<[S]> = s1[0].all.upgrade().unwrap();
1606 assert!(Src::ptr_eq(&s1, &s2));
1607 }
1608 { // panic
1609 let drop_flags: [_; 6] = std::array::from_fn(|_| AssertUnwindSafe(Cell::new(false)));
1610 struct DropFlagger<'a>(&'a Cell<bool>);
1611 impl Drop for DropFlagger<'_> {
1612
1613 fn drop(&mut self) {
1614 self.0.update(|v| !v)
1615 }
1616
1617 }
1618 let _: Result<_, _> = catch_unwind(|| {
1619 let _: Src<[DropFlagger<'_>]> = Src::cyclic_from_fn(drop_flags.len(), |_, i| {
1620 if i >= 3 { panic!() }
1621 DropFlagger(&drop_flags[i])
1622 });
1623 });
1624 assert!(drop_flags[..3].iter().map(Deref::deref).all(Cell::get));
1625 assert!(!drop_flags[3..].iter().map(Deref::deref).any(Cell::get));
1626 }
1627 }
1628
1629 #[test]
1630 fn from_iter() {
1631 let s: Src<[u8]> = Src::from_iter(vec![1, 2, 3].into_iter().map(|i| i * 2));
1632 assert_eq!(*s, [2, 4, 6]);
1633 }
1634
1635 #[test]
1636 fn from_array() {
1637 let s: Src<[u8]> = Src::from_array([1, 2, 3]);
1638 assert_eq!(*s, [1, 2, 3]);
1639 }
1640
1641 #[test]
1642 fn from_default() {
1643 #[derive(Copy, Clone, Eq, PartialEq, Debug)]
1644 struct D42(u8);
1645 impl Default for D42 {
1646
1647 fn default() -> Self {
1648 Self(42)
1649 }
1650
1651 }
1652 let s: Src<[u8]> = Src::from_default(3);
1653 assert_eq!(*s, [0, 0, 0]);
1654 let s: Src<[D42]> = Src::from_default(3);
1655 assert_eq!(*s, [D42(42), D42(42), D42(42)]);
1656 }
1657
1658 #[test]
1659 fn filled() {
1660 let s: Src<[u8]> = Src::filled(3, &42);
1661 assert_eq!(*s, [42, 42, 42]);
1662 }
1663
1664 #[test]
1665 fn filled_cyclic() {
1666 { // non-cyclic
1667 let s: Src<[u8]> = Src::filled_cyclic(3, |_| 42);
1668 assert_eq!(*s, [42, 42, 42]);
1669 }
1670 { // cyclic
1671 #[derive(Clone)]
1672 struct S {
1673
1674 all: WeakSrc<[S]>,
1675 i: usize,
1676
1677 }
1678 let s: Src<[S]> = Src::filled_cyclic(3, |weak| S { all: weak.clone(), i: 42 });
1679 assert_eq!(s[0].i, 42);
1680 assert_eq!(s[1].i, 42);
1681 assert_eq!(s[2].i, 42);
1682 let w: WeakSrc<[S]> = Src::downgrade(&s);
1683 assert!(WeakSrc::ptr_eq(&s[0].all, &w));
1684 }
1685 }
1686
1687 #[test]
1688 fn cloned() {
1689 #[derive(Clone, Eq, PartialEq, Debug)]
1690 struct NonCopy(u8);
1691 let s: Src<[NonCopy]> = Src::cloned(&[NonCopy(1), NonCopy(2), NonCopy(3)]);
1692 assert_eq!(*s, [NonCopy(1), NonCopy(2), NonCopy(3)]);
1693 }
1694
1695 #[test]
1696 fn copied() {
1697 let s: Src<[u8]> = Src::copied(&[1, 2, 3]);
1698 assert_eq!(*s, [1, 2, 3]);
1699 }
1700
1701 #[test]
1702 fn assume_init_single() {
1703 let s: Src<MaybeUninit<u8>> = Src::single_zeroed();
1704 // SAFETY: u8 is a zeroable type
1705 let s: Src<u8> = unsafe { s.assume_init() };
1706 assert_eq!(*s, 0);
1707 }
1708
1709 #[test]
1710 fn assume_init_slice() {
1711 let s: Src<[MaybeUninit<u8>]> = Src::new_zeroed(3);
1712 // SAFETY: u8 is a zeroable type
1713 let s: Src<[u8]> = unsafe { s.assume_init() };
1714 assert_eq!(*s, [0, 0, 0]);
1715 }
1716
1717 #[test]
1718 fn new() {
1719 let s: Src<str> = Src::new("Hello World!");
1720 assert_eq!(&*s, "Hello World!");
1721 }
1722
1723 #[test]
1724 fn from_utf8() {
1725 { // UTF-8
1726 let s: Src<[u8]> = Src::copied(b"Hello World!");
1727 let s: Src<str> = Src::from_utf8(s).unwrap();
1728 assert_eq!(&*s, "Hello World!");
1729 }
1730 { // not UTF-8
1731 let s: Src<[u8]> = Src::copied(&[0xFF]);
1732 let _: Utf8Error = Src::from_utf8(s).unwrap_err();
1733 }
1734 }
1735
1736 #[test]
1737 fn from_utf8_unchecked() {
1738 let s: Src<[u8]> = Src::copied(b"Hello World!");
1739 // SAFETY: just got the bytes from a str
1740 let s: Src<str> = unsafe { Src::from_utf8_unchecked(s) };
1741 assert_eq!(&*s, "Hello World!");
1742 }
1743
1744 #[test]
1745 fn as_bytes() {
1746 let s: Src<str> = Src::new("Hello World!");
1747 let s: Src<[u8]> = Src::as_bytes(&s);
1748 assert_eq!(&*s, b"Hello World!");
1749 }
1750
1751 #[test]
1752 fn clone() {
1753 let s1: Src<[u8]> = Src::from_array([1, 2, 3]);
1754 assert_eq!(Src::strong_count(&s1), 1);
1755 let s2: Src<[u8]> = s1.clone();
1756 assert_eq!(Src::strong_count(&s1), 2);
1757 assert_eq!(*s1, *s2);
1758 assert!(Src::ptr_eq(&s1, &s2));
1759 }
1760
1761 #[test]
1762 fn deref() {
1763 let s: Src<[u8]> = Src::from_array([1, 2, 3]);
1764 assert_eq!(Deref::deref(&s), &[1, 2, 3]);
1765 }
1766
1767 #[test]
1768 fn drop() {
1769 let drop_flags: [_; 3] = std::array::from_fn(|_| Cell::new(false));
1770 struct DropFlagger<'a>(&'a Cell<bool>);
1771 impl Drop for DropFlagger<'_> {
1772
1773 fn drop(&mut self) {
1774 self.0.update(|v| !v)
1775 }
1776
1777 }
1778 assert!(!drop_flags.iter().any(Cell::get));
1779 let s1: Src<[DropFlagger<'_>]> = Src::from_iter(drop_flags.iter().map(DropFlagger));
1780 assert!(!drop_flags.iter().any(Cell::get));
1781 assert_eq!(Src::strong_count(&s1), 1);
1782 let s2: Src<[DropFlagger<'_>]> = s1.clone();
1783 assert!(!drop_flags.iter().any(Cell::get));
1784 assert_eq!(Src::strong_count(&s1), 2);
1785 assert_eq!(Src::strong_count(&s2), 2);
1786 std::mem::drop(s1);
1787 assert!(!drop_flags.iter().any(Cell::get));
1788 assert_eq!(Src::strong_count(&s2), 1);
1789 std::mem::drop(s2);
1790 assert!(drop_flags.iter().all(Cell::get));
1791 }
1792
1793}