pub struct WeakSrc<T: SrcTarget + ?Sized> { /* private fields */ }Expand description
WeakSrc is a version of Src that holds a non-owning reference to the managed allocation.
This is this crate’s analog to std::rc::Weak; see the crate-level documentation for a description of how this crate’s types differ from those of std::rc.
The allocation is accessed by calling upgrade on the WeakSrc pointer, which returns an Option<Src<T>>.
Since a WeakSrc pointer does not count toward ownership, it will not prevent the value stored in the allocation from being dropped,
and WeakSrc itself makes no guarantees about the value still being present. Thus it may return None when upgraded.
Note however that a WeakSrc does prevent the allocation itself (the backing store) from being deallocated.
A WeakSrc pointer is useful for keeping a temporary reference to the allocation managed by Src without preventing its inner value from being dropped.
It is also used to prevent circular references between Src pointers, since mutual owning references would never allow either Src to be dropped.
For example, a tree could have strong Src pointers from parent nodes to children, and WeakSrc pointers from children back to their parents.
The typical way to obtain a WeakSrc pointer is to call Src::downgrade.
§Dangling
WeakSrc::dangling allows constructing a “dangling” WeakSrc pointer;
dangling WeakSrc pointers don’t have a backing allocation, and as such, are guaranteed to return None from WeakSrc::upgrade.
Dangling WeakSrcs are considered root and empty.
WeakSrc pointers which are attached to an allocation are not considered dangling,
even if that allocation has been dropped or the WeakSrc is otherwise un-upgradeable.
Implementations§
Source§impl<T: SrcTarget + ?Sized> WeakSrc<T>
 
impl<T: SrcTarget + ?Sized> WeakSrc<T>
Sourcepub fn is_dangling(&self) -> bool
 
pub fn is_dangling(&self) -> bool
Returns true if this WeakSrc is dangling.
This only returns true for WeakSrcs that were constructed from WeakSrc::dangling;
WeakSrcs that are un-upgradeable for other reasons are not considered dangling,
and therefore this method returns false for those cases.
§Examples
use slice_rc::WeakSrc;
 
let dangling = WeakSrc::<i32>::dangling();
 
assert!(dangling.is_dangling());Not dangling:
let s = Src::single(42);
let w = Src::downgrade(&s);
drop(s);
 
assert!(!w.is_dangling());
assert!(w.upgrade().is_none());Sourcepub fn upgrade(&self) -> Option<Src<T>>
 
pub fn upgrade(&self) -> Option<Src<T>>
Attempts to upgrade the WeakSrc pointer to an Src, delaying dropping the inner value if successful.
Returns None if the inner value has since been dropped,
if the inner value is uniquely owned by a UniqueSrc,
or if the inner value is uninitialized via UninitSrc or one of the cyclic helper methods, e.g. Src::cyclic_from_fn.
§Examples
use slice_rc::Src;
 
let five = Src::single(5);
 
let weak_five = Src::downgrade(&five);
 
let strong_five = weak_five.upgrade();
assert!(strong_five.is_some());
 
drop(strong_five);
drop(five);
 
assert!(weak_five.upgrade().is_none());Sourcepub fn ptr_eq<U: SrcTarget<Item = T::Item> + ?Sized>(
    &self,
    other: &WeakSrc<U>,
) -> bool
 
pub fn ptr_eq<U: SrcTarget<Item = T::Item> + ?Sized>( &self, other: &WeakSrc<U>, ) -> bool
Returns true if the two WeakSrcs point to slices starting at the same location in memory or are both dangling, akin to ptr::eq.
use slice_rc::{Src, WeakSrc};
 
let slice = Src::from_array([1, 2, 3]);
let weak_slice = Src::downgrade(&slice);
let same_weak_slice = weak_slice.clone();
let weak_sub_slice = weak_slice.slice(1..);
let other_slice = Src::from_array([1, 2, 3]);
let other_weak_slice = Src::downgrade(&other_slice);
 
assert!(WeakSrc::ptr_eq(&weak_slice, &same_weak_slice));
assert!(!WeakSrc::ptr_eq(&weak_slice, &weak_sub_slice));
assert!(!WeakSrc::ptr_eq(&weak_slice, &other_weak_slice));If WeakSrc::ptr_eq(&a, &b) returns true, then WeakSrc::same_root(&a, &b) will also be true.
The type parameter, U, is to allow WeakSrcs of different types that could be of the same allocation, and therefore, could be equal by pointer, to be compared, e.g.:
let strong: Src<i32> = Src::single(4);
let single: WeakSrc<i32> = Src::downgrade(&strong);
let slice: WeakSrc<[i32]> = single.as_slice();
 
assert!(WeakSrc::ptr_eq(&single, &slice));Note that this method currently ignores the length of the slice:
let root_strong = Src::from_array([1, 2, 3]);
let root = Src::downgrade(&root_strong);
let first = root.slice(0);
 
assert!(WeakSrc::ptr_eq(&root, &first));
 
let mid_to_end_slice = root.slice(1..);
let mid_slice = root.slice(1..=1);
 
assert!(WeakSrc::ptr_eq(&mid_to_end_slice, &mid_slice));It is undecided whether this behavior is desireable, and as such, it may change;
notably, Weak::ptr_eq does ignore metadata for ?Sized types
(though that’s irrelevant for slices because Weaks can only point to the whole slice, and therefore the length will always be the same for Weaks that point to the same allocation),
while ptr::eq does consider the metadata (which causes inconsistent results for trait objects, but that is irrelevant here because WeakSrcs don’t support trait objects).
See also WeakSrc::same_root.
Sourcepub fn same_root<U: SrcTarget<Item = T::Item> + ?Sized>(
    &self,
    other: &WeakSrc<U>,
) -> bool
 
pub fn same_root<U: SrcTarget<Item = T::Item> + ?Sized>( &self, other: &WeakSrc<U>, ) -> bool
Returns true if the two WeakSrcs share the same root (i.e., they point to parts of the same allocation) or are both dangling.
use slice_rc::{Src, WeakSrc};
 
let slice = Src::from_array([1, 2, 3]);
let weak_slice = Src::downgrade(&slice);
let same_weak_slice = weak_slice.clone();
let other_slice = Src::from_array([1, 2, 3]);
let other_weak_slice = Src::downgrade(&other_slice);
 
assert!(WeakSrc::same_root(&weak_slice, &same_weak_slice));
assert!(!WeakSrc::same_root(&weak_slice, &other_weak_slice));Notably, neither slice has to be the root, nor do they need to overlap at all:
let strong = Src::from_array([1, 2, 3]);
let root = Src::downgrade(&strong);
let a = root.slice(..1);
let b = root.slice(2..);
 
assert!(WeakSrc::same_root(&a, &b));The type parameter, U, is to allow WeakSrcs of different types that could share the same root, to be compared, e.g.:
let strong: Src<i32> = Src::single(4);
let single: WeakSrc<i32> = Src::downgrade(&strong);
let slice: WeakSrc<[i32]> = single.as_slice();
 
assert!(WeakSrc::same_root(&single, &slice));This method ignores the length of the slices in question, but unlike WeakSrc::ptr_eq, this will not change,
as the roots remains the same regardless of which parts of it are included in these slices.
See also WeakSrc::ptr_eq, WeakSrc::is_root, and WeakSrc::root.
Sourcepub fn is_root(&self) -> bool
 
pub fn is_root(&self) -> bool
Returns true if this WeakSrc contains its root (i.e., it references its entire allocation), or is dangling.
Notably, this WeakSrc does not have to be the first one that was initialized, it just has to cover the entire allocation.
use slice_rc::Src;
 
let strong = Src::from_array([1, 2, 3]);
let root = Src::downgrade(&strong);
let also_root = root.slice(..);
let slice = root.slice(1..);
 
assert!(root.is_root());
assert!(also_root.is_root());
assert!(!slice.is_root());See also WeakSrc::same_root and WeakSrc::root.
Sourcepub fn strong_count(&self) -> usize
 
pub fn strong_count(&self) -> usize
Sourcepub fn weak_count(&self) -> usize
 
pub fn weak_count(&self) -> usize
Gets the number of WeakSrc pointers pointing to this allocation.
If no strong pointers remain (or this WeakSrc is otherwise un-upgradeable), this will return 0.
Sourcepub fn root(&self) -> WeakSrc<[T::Item]>
 
pub fn root(&self) -> WeakSrc<[T::Item]>
Returns a WeakSrc pointer that refers to this WeakSrc’s root (i.e., the entire allocation).
use slice_rc::Src;
 
let strong = Src::from_array([1, 2, 3]);
let root = Src::downgrade(&strong);
let slice = root.slice(1..);
drop(root);
 
assert_eq!(*slice.upgrade().unwrap(), [2, 3]);
 
let new_root = slice.root();
 
assert_eq!(*new_root.upgrade().unwrap(), [1, 2, 3]);This method returns a WeakSrc<[T::Item]> rather than a WeakSrc<T> for two reasons:
- If 
T: Sized, then the root can only be aWeakSrc<T>if its total length is is1, which would prevent situations like this: 
let strong = Src::from_array([1, 2, 3]);
let root: WeakSrc<[i32]> = Src::downgrade(&strong);
let slice: WeakSrc<i32> = root.slice(1);
let new_root: WeakSrc<[i32]> = slice.root();
 
assert_eq!(*new_root.upgrade().unwrap(), [1, 2, 3]);- If 
T = str, it could be a UTF-8 slice of a larger allocation that is not entirely UTF-8, which would violate the safety invariant ofstr: 
let root: Src<[u8]> = Src::copied(b"\xFFhello");
let weak_root: WeakSrc<[u8]> = Src::downgrade(&root);
let s: Src<str> = Src::from_utf8(root.slice(1..)).unwrap();
let weak_s: WeakSrc<str> = Src::downgrade(&s);
let new_weak_root: WeakSrc<[u8]> = weak_s.root();
 
assert_eq!(&*weak_s.upgrade().unwrap(), "hello");
assert!(Src::from_utf8(new_weak_root.upgrade().unwrap()).is_err());Source§impl<T: SrcSlice + ?Sized> WeakSrc<T>
 
impl<T: SrcSlice + ?Sized> WeakSrc<T>
Sourcepub fn is_empty(&self) -> bool
 
pub fn is_empty(&self) -> bool
Returns true if this WeakSrc has a length of 0 or is dangling.
use slice_rc::Src;
 
let a_strong = Src::from_array([1, 2, 3]);
let a = Src::downgrade(&a_strong);
assert!(!a.is_empty());
 
let b_strong = Src::<[i32]>::from_array([]);
let b = Src::downgrade(&b_strong);
assert!(b.is_empty());Source§impl<T: Sized> WeakSrc<T>
 
impl<T: Sized> WeakSrc<T>
Sourcepub fn as_slice(&self) -> WeakSrc<[T]>
 
pub fn as_slice(&self) -> WeakSrc<[T]>
Returns a WeakSrc equivalent to this one, but typed as a slice rather than a single element.
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.
use slice_rc::{Src, WeakSrc};
use std::ptr;
 
let strong = Src::single(42);
let single = Src::downgrade(&strong);
let slice = single.as_slice();
 
assert!(WeakSrc::ptr_eq(&single, &slice));
assert!(ptr::eq(&*single.upgrade().unwrap(), &slice.upgrade().unwrap()[0]));Source§impl<T> WeakSrc<[T]>
 
impl<T> WeakSrc<[T]>
Sourcepub fn slice<I: WeakSrcIndex<[T]>>(&self, index: I) -> WeakSrc<I::Output>
 
pub fn slice<I: WeakSrcIndex<[T]>>(&self, index: I) -> WeakSrc<I::Output>
Returns a WeakSrc pointer to an element or subslice depending on the type of index.
- If given a position (only applicable where 
Self = WeakSrc<[U]>), returns anWeakSrc<U>to the element at that position. - If given a range, returns the subslice corresponding to that range.
 
This method is only provided for WeakSrc<[T]>, not WeakSrc<str>;
this is because str requires analyzing the value to validate that the new range is falls on char boundaries,
and therefore the WeakStr must be upgraded to slice it.
On the other hand, this is an acceptable compromise because the primary use-case of this method is during cyclic initialization,
which is meaningless for str.
§Panics
If the index is in some way out of bounds. Note that dangling pointers are considered empty.
§Examples
use slice_rc::Src;
 
let v = Src::from_array([10, 40, 30]);
let weak = Src::downgrade(&v);
assert_eq!(Src::single(40), weak.slice(1).upgrade().unwrap());
assert_eq!(Src::from_array([10, 40]), weak.slice(0..2).upgrade().unwrap());Panics:
let v = Src::from_array([10, 40, 30]);
let weak = Src::downgrade(&v);
let _ = weak.slice(3);
let _ = weak.slice(0..4);