Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into clone
Browse files Browse the repository at this point in the history
  • Loading branch information
aminya committed Oct 23, 2023
2 parents 0b06475 + e02c1b2 commit 138d36d
Show file tree
Hide file tree
Showing 5 changed files with 297 additions and 0 deletions.
66 changes: 66 additions & 0 deletions src/index_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,24 @@ impl<K: Eq + Hash, V> FrozenIndexMap<K, V> {
impl<K: Eq + Hash, V: StableDeref, S: BuildHasher> FrozenIndexMap<K, V, S> {
// these should never return &K or &V
// these should never delete any entries
//
/// If the key exists in the map, returns a reference to the corresponding
/// value, otherwise inserts a new entry in the map for that key
/// and returns a reference to the generated value.
///
/// Existing values are never overwritten.
///
/// The key may be any borrowed form of the map's key type, but
/// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
/// the key type.
///
/// # Example
/// ```
/// use elsa::index_map::FrozenIndexMap;
/// let map = FrozenIndexMap::new();
/// assert_eq!(map.insert(1, Box::new("a")), &"a");
/// assert_eq!(map.insert(1, Box::new("b")), &"a");
/// ```
pub fn insert(&self, k: K, v: V) -> &V::Target {
assert!(!self.in_use.get());
self.in_use.set(true);
Expand All @@ -47,6 +65,24 @@ impl<K: Eq + Hash, V: StableDeref, S: BuildHasher> FrozenIndexMap<K, V, S> {

// these should never return &K or &V
// these should never delete any entries
//
/// If the key exists in the map, returns a reference to the corresponding
/// value and its index, otherwise inserts a new entry in the map for that key
/// and returns a reference to the generated value and its index.
///
/// Existing values are never overwritten.
///
/// The key may be any borrowed form of the map's key type, but
/// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
/// the key type.
///
/// # Example
/// ```
/// use elsa::index_map::FrozenIndexMap;
/// let map = FrozenIndexMap::new();
/// assert_eq!(map.insert_full(12, Box::new("a")), (0, &"a"));
/// assert_eq!(map.insert_full(12, Box::new("b")), (0, &"a"));
/// ```
pub fn insert_full(&self, k: K, v: V) -> (usize, &V::Target) {
assert!(!self.in_use.get());
self.in_use.set(true);
Expand Down Expand Up @@ -91,6 +127,23 @@ impl<K: Eq + Hash, V: StableDeref, S: BuildHasher> FrozenIndexMap<K, V, S> {
ret
}

/// Returns a reference to the key-value mapping corresponding to an index.
///
/// The key may be any borrowed form of the map's key type, but
/// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
/// the key type.
///
/// # Examples
///
/// ```
/// use elsa::index_map::FrozenIndexMap;
///
/// let map = FrozenIndexMap::new();
/// let (idx, _ref) = map.insert_full(Box::new("foo"), Box::new("a"));
/// assert_eq!(idx, 0);
/// assert_eq!(map.get_index(idx), Some((&"foo", &"a")));
/// assert_eq!(map.get_index(idx + 1), None);
/// ```
pub fn get_index(&self, index: usize) -> Option<(&K::Target, &V::Target)>
where
K: StableDeref,
Expand Down Expand Up @@ -248,3 +301,16 @@ impl<K: Clone, V: Clone, S: Clone> Clone for FrozenIndexMap<K, V, S> {
return self_clone;
}
}

impl<T: Hash + Eq, S: PartialEq> PartialEq for FrozenIndexMap<T, S> {
fn eq(&self, other: &Self) -> bool {
assert!(!self.in_use.get());
assert!(!other.in_use.get());
self.in_use.set(true);
other.in_use.set(true);
let ret = unsafe { *self.map.get() == *other.map.get() };
self.in_use.set(false);
other.in_use.set(false);
ret
}
}
82 changes: 82 additions & 0 deletions src/index_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,24 @@ impl<T: Eq + Hash> FrozenIndexSet<T> {
impl<T: Eq + Hash + StableDeref, S: BuildHasher> FrozenIndexSet<T, S> {
// these should never return &T
// these should never delete any entries
//
/// If the value exists in the set, returns a reference to the corresponding
/// value, otherwise inserts a new entry in the set for that value
/// and returns a reference to it.
///
/// Existing values are never overwritten.
///
/// # Example
/// ```
/// use elsa::index_set::FrozenIndexSet;
/// let set = FrozenIndexSet::new();
/// let a_ref = set.insert(Box::new("a"));
/// let aa = "a";
/// let other_a_ref = unsafe { aa.as_ptr() as *const &str};
/// let other_a = Box::new(aa);
/// assert!(!std::ptr::eq(a_ref, other_a_ref));
/// assert!(std::ptr::eq(a_ref, set.insert(other_a)));
/// ```
pub fn insert(&self, value: T) -> &T::Target {
assert!(!self.in_use.get());
self.in_use.set(true);
Expand All @@ -45,6 +63,19 @@ impl<T: Eq + Hash + StableDeref, S: BuildHasher> FrozenIndexSet<T, S> {

// these should never return &T
// these should never delete any entries
/// If the key exists in the set, returns a reference to the corresponding
/// value and its index, otherwise inserts a new entry in the set for that value
/// and returns a reference to it and its index.
///
/// Existing values are never overwritten.
///
/// # Example
/// ```
/// use elsa::index_set::FrozenIndexSet;
/// let map = FrozenIndexSet::new();
/// assert_eq!(map.insert_full(Box::new("a")), (0, &"a"));
/// assert_eq!(map.insert_full(Box::new("b")), (1, &"b"));
/// ```
pub fn insert_full(&self, value: T) -> (usize, &T::Target) {
assert!(!self.in_use.get());
self.in_use.set(true);
Expand Down Expand Up @@ -84,6 +115,18 @@ impl<T: Eq + Hash + StableDeref, S: BuildHasher> FrozenIndexSet<T, S> {
// }
// }

/// Returns a reference to the value passed as argument if present in the set.
///
/// # Examples
///
/// ```
/// use elsa::index_set::FrozenIndexSet;
///
/// let set = FrozenIndexSet::new();
/// set.insert(Box::new("a"));
/// assert_eq!(set.get(&Box::new("a")), Some(&"a"));
/// assert_eq!(set.get(&Box::new("b")), None);
/// ```
pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&T::Target>
where
T: Borrow<Q>,
Expand All @@ -99,6 +142,19 @@ impl<T: Eq + Hash + StableDeref, S: BuildHasher> FrozenIndexSet<T, S> {
ret
}

/// Returns a reference to the value passed as argument if present in the set,
/// along with its index
///
/// # Examples
///
/// ```
/// use elsa::index_set::FrozenIndexSet;
///
/// let set = FrozenIndexSet::new();
/// set.insert(Box::new("a"));
/// assert_eq!(set.get_full(&Box::new("a")), Some((0, &"a")));
/// assert_eq!(set.get_full(&Box::new("b")), None);
/// ```
pub fn get_full<Q: ?Sized>(&self, k: &Q) -> Option<(usize, &T::Target)>
where
T: Borrow<Q>,
Expand All @@ -114,6 +170,19 @@ impl<T: Eq + Hash + StableDeref, S: BuildHasher> FrozenIndexSet<T, S> {
ret
}

/// Returns a reference to value at the index passed as argument, if
/// present in the set.
///
/// # Examples
///
/// ```
/// use elsa::index_set::FrozenIndexSet;
///
/// let set = FrozenIndexSet::new();
/// set.insert(Box::new("a"));
/// assert_eq!(set.get_index(0), Some(&"a"));
/// assert_eq!(set.get_index(1), None);
/// ```
pub fn get_index(&self, index: usize) -> Option<&T::Target> {
assert!(!self.in_use.get());
self.in_use.set(true);
Expand Down Expand Up @@ -193,3 +262,16 @@ impl<K: Clone, V: Clone> Clone for FrozenIndexSet<K, V> {
return self_clone;
}
}

impl<T: Hash + Eq, S: BuildHasher> PartialEq for FrozenIndexSet<T, S> {
fn eq(&self, other: &Self) -> bool {
assert!(!self.in_use.get());
assert!(!other.in_use.get());
self.in_use.set(true);
other.in_use.set(true);
let ret = unsafe { *self.set.get() == *other.set.get() };
self.in_use.set(false);
other.in_use.set(false);
ret
}
}
13 changes: 13 additions & 0 deletions src/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -521,3 +521,16 @@ impl<K: Clone, V: Clone> Clone for FrozenBTreeMap<K, V> {
return self_clone;
}
}

impl<K: Eq + Hash, V: PartialEq + StableDeref> PartialEq for FrozenMap<K, V> {
fn eq(&self, other: &Self) -> bool {
assert!(!self.in_use.get());
assert!(!other.in_use.get());
self.in_use.set(true);
other.in_use.set(true);
let ret = self.map.get() == other.map.get();
self.in_use.set(false);
other.in_use.set(false);
ret
}
}
Loading

0 comments on commit 138d36d

Please sign in to comment.