Skip to content

Commit

Permalink
Implement ptr_eq
Browse files Browse the repository at this point in the history
  • Loading branch information
arthurprs authored and orium committed Aug 7, 2023
1 parent ef965e3 commit e4675f1
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 11 deletions.
10 changes: 7 additions & 3 deletions src/map/hash_trie_map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -948,13 +948,17 @@ where
H: Clone,
P: SharedPointerKind,
{
pub(crate) fn same_root<PO: SharedPointerKind, I: BuildHasher>(
/// Test whether the two maps refer to the same content in memory.
///
/// This would return true if you’re comparing a map to itself,
/// or if you’re comparing a map to a fresh clone of itself.
pub fn ptr_eq<PO: SharedPointerKind, I: BuildHasher>(
&self,
other: &HashTrieMap<K, V, PO, I>,
) -> bool {
let a = SharedPointer::as_ptr(&self.root).cast::<Node<K, V, P>>();
// Note how we're casting the raw pointer changing from P to PO
// We cannot perform the equality it in a type safe way because the Root type depends
// We cannot perform the equality in a type safe way because the Root type depends
// on P/PO, and we can't pass different types to SharedPtr::same_ptr or std::ptr::eq.
let b = SharedPointer::as_ptr(&other.root).cast::<Node<K, V, P>>();
core::ptr::eq(a, b)
Expand All @@ -970,7 +974,7 @@ where
PO: SharedPointerKind,
{
fn eq(&self, other: &HashTrieMap<K, V, PO, H>) -> bool {
if self.same_root(other) {
if self.ptr_eq(other) {
return true;
}
self.size() == other.size()
Expand Down
13 changes: 7 additions & 6 deletions src/map/red_black_tree_map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1010,13 +1010,14 @@ impl<K, V, P> RedBlackTreeMap<K, V, P>
where
P: SharedPointerKind,
{
pub(crate) fn same_root<PO: SharedPointerKind>(
&self,
other: &RedBlackTreeMap<K, V, PO>,
) -> bool {
/// Test whether the two maps refer to the same content in memory.
///
/// This would return true if you’re comparing a map to itself,
/// or if you’re comparing a map to a fresh clone of itself.
pub fn ptr_eq<PO: SharedPointerKind>(&self, other: &RedBlackTreeMap<K, V, PO>) -> bool {
let a = self.root.as_ref().map_or(core::ptr::null(), SharedPointer::as_ptr);
// Note how we're casting the raw pointer changing from P to PO
// We cannot perform the equality it in a type safe way because the Root type depends
// We cannot perform the equality in a type safe way because the Root type depends
// on P/PO, and we can't pass different types to SharedPtr::same_ptr or std::ptr::eq.
let b = other
.root
Expand All @@ -1034,7 +1035,7 @@ where
PO: SharedPointerKind,
{
fn eq(&self, other: &RedBlackTreeMap<K, V, PO>) -> bool {
if self.same_root(other) {
if self.ptr_eq(other) {
return true;
}
self.size() == other.size()
Expand Down
20 changes: 19 additions & 1 deletion src/set/hash_trie_set/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ where

#[must_use]
pub fn is_subset<I: BuildHasher + Clone>(&self, other: &HashTrieSet<T, P, I>) -> bool {
if self.map.same_root(&other.map) {
if self.ptr_eq(other) {
return true;
}

Expand Down Expand Up @@ -263,6 +263,24 @@ where
}
}

impl<T, P, H: BuildHasher> HashTrieSet<T, P, H>
where
T: Eq + Hash,
H: Clone,
P: SharedPointerKind,
{
/// Test whether the two sets refer to the same content in memory.
///
/// This would return true if you’re comparing a set to itself,
/// or if you’re comparing a set to a fresh clone of itself.
pub fn ptr_eq<PO: SharedPointerKind, I: BuildHasher + Clone>(
&self,
other: &HashTrieSet<T, PO, I>,
) -> bool {
self.map.ptr_eq(&other.map)
}
}

impl<T: Eq, P, PO, H: BuildHasher> PartialEq<HashTrieSet<T, PO, H>> for HashTrieSet<T, P, H>
where
T: Hash,
Expand Down
16 changes: 15 additions & 1 deletion src/set/red_black_tree_set/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ where
where
PO: SharedPointerKind,
{
if self.map.same_root(&other.map) {
if self.ptr_eq(other) {
return true;
}
if self.size() > other.size() {
Expand Down Expand Up @@ -295,6 +295,20 @@ where
}
}

impl<T, P> RedBlackTreeSet<T, P>
where
T: Ord,
P: SharedPointerKind,
{
/// Test whether the two sets refer to the same content in memory.
///
/// This would return true if you’re comparing a set to itself,
/// or if you’re comparing a set to a fresh clone of itself.
pub fn ptr_eq<PO: SharedPointerKind>(&self, other: &RedBlackTreeSet<T, PO>) -> bool {
self.map.ptr_eq(&other.map)
}
}

impl<T, P, PO> PartialEq<RedBlackTreeSet<T, PO>> for RedBlackTreeSet<T, P>
where
T: Ord,
Expand Down

0 comments on commit e4675f1

Please sign in to comment.