[][src]Struct hashable_rc::HashableWeak

pub struct HashableWeak<T> { /* fields omitted */ }

A hashable wrapper around the Weak<T> type.

A hash of a HashableWeak<T> is taken from the underlying pointer. Therefore, two separate objects that may be considered equal will, when contained in a HashableWeak<T>, almost always have different hashed values. For example, the following holds:

use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
use std::rc::Rc;

use hashable_rc::HashableWeak;

fn hash<H: Hash>(value: &H) -> u64 {
    let mut state = DefaultHasher::new();
    value.hash(&mut state);
    state.finish()
}

// While the underlying values are considered equal, the hash values
// will be different, due to being separate allocated objects with 
// different underlying pointers.
let rc1 = Rc::new(42);
let rc2 = Rc::new(42);
 
// The hashes of the two reference countings are different.
assert_ne!(hash(&HashableWeak::new(Rc::downgrade(&rc1))), 
           hash(&HashableWeak::new(Rc::downgrade(&rc2))));

// Contrastingly, the hashes of clone reference countings pointing to 
// the same object are the equal.
assert_eq!(hash(&HashableWeak::new(Rc::downgrade(&rc1))), 
           hash(&HashableWeak::new(Rc::downgrade(&rc1))));

Similarly, equality of HashableWeak<T> objects is done by evaluating pointer equality (using ptr_eq()). The equality is not from the value itself, but from the pointer.

use std::rc::Rc;

use hashable_rc::HashableWeak;

// Again, the values contained are equal, but the underlying pointers
// are different.
let rc1 = Rc::new(42);
let rc2 = Rc::new(42);

// Therefore, two HashableWeak wrappers containing these reference
// counters are not equal.
assert_ne!(HashableWeak::new(Rc::downgrade(&rc1)),
           HashableWeak::new(Rc::downgrade(&rc2)));

// But HashableWeak holding the same underlying object are equal.
assert_eq!(HashableWeak::new(Rc::downgrade(&rc1)),
           HashableWeak::new(Rc::downgrade(&rc1)));

Since Weak<T> is a weak reference, the underlying value is not guaranteed to exist. A Weak<T> that is empty can still be wrapped in a HashableWeak<T>.

use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
use std::rc::{Rc, Weak};

use hashable_rc::HashableWeak;

fn hash<H: Hash>(value: &H) -> u64 {
    let mut state = DefaultHasher::new();
    value.hash(&mut state);
    state.finish()
}
 
let weak: Weak<i32> = Weak::new();
let rc = Rc::new(0);

// Hashing still works for a HashableWeak pointing to no value. It will
// hash differently than HashableWeak objects containing values, and
// will hash the same as other empty HashableWeak objects.
assert_ne!(hash(&HashableWeak::new(weak.clone())), 
           hash(&HashableWeak::new(Rc::downgrade(&rc))));
assert_eq!(hash(&HashableWeak::new(weak.clone())), 
           hash(&HashableWeak::new(weak.clone())));

// Empty HashableWeak objects are also not equal to assigned 
// HashableWeak objects, while being equal to other empty HashableWeak
// objects.
assert_ne!(HashableWeak::new(weak.clone()), 
           HashableWeak::new(Rc::downgrade(&rc)));
assert_eq!(HashableWeak::new(weak.clone()), 
           HashableWeak::new(weak.clone()));

Implementations

impl<T> HashableWeak<T>[src]

pub fn new(value: Weak<T>) -> Self[src]

Constructs a new HashableWeak<T> wrapping a Weak<T>.

Trait Implementations

impl<T: Debug> Debug for HashableWeak<T>[src]

impl<T> Eq for HashableWeak<T>[src]

impl<T> Hash for HashableWeak<T>[src]

fn hash<H>(&self, state: &mut H) where
    H: Hasher
[src]

Generate a hash value for the HashableWeak<T>.

This hash value is based on the underlying pointer. Two unique objects will most likely have different hashes, even if their values are the same.

If no value is pointed to, the Hasher state remains unaltered.

impl<T> PartialEq<HashableWeak<T>> for HashableWeak<T>[src]

fn eq(&self, other: &Self) -> bool[src]

Equality for two HashableWeak<T> objects.

Equality is determined by pointer equality, rather than value equality. Objects are only considered equal if they point to the same object (or if both point to no object).

Auto Trait Implementations

impl<T> !RefUnwindSafe for HashableWeak<T>

impl<T> !Send for HashableWeak<T>

impl<T> !Sync for HashableWeak<T>

impl<T> Unpin for HashableWeak<T>

impl<T> !UnwindSafe for HashableWeak<T>

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.