From 7104e30f64559c90165be255fa5879ea114708a3 Mon Sep 17 00:00:00 2001 From: DanikVitek Date: Mon, 16 Feb 2026 21:23:59 +0200 Subject: [PATCH] feat!: Use `equivalent` for Map and Set getters --- Cargo.lock | 7 ++ Cargo.toml | 1 + benches/hashmap.rs | 1 + benches/ordmap.rs | 8 +- src/hash/map.rs | 75 ++++++++---------- src/hash/set.rs | 28 ++++--- src/nodes/btree.rs | 76 ++++++++---------- src/nodes/hamt.rs | 70 +++++++---------- src/ord/map.rs | 190 +++++++++++++++++++++------------------------ src/ord/set.rs | 72 ++++++++--------- 10 files changed, 241 insertions(+), 287 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cc01340..72d531c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -243,6 +243,12 @@ dependencies = [ "regex", ] +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + [[package]] name = "errno" version = "0.3.13" @@ -307,6 +313,7 @@ dependencies = [ "bincode", "bitmaps", "criterion", + "equivalent", "half", "imbl-sized-chunks", "metrohash", diff --git a/Cargo.toml b/Cargo.toml index d67e201..7842959 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,6 +52,7 @@ rayon = { version = "1", optional = true } arbitrary = { version = "1.0", optional = true } bincode = {version = "2.0.1", optional = true, default-features=false, features = ["alloc", "std"]} wide = "0.7" +equivalent = "1.0.2" [dev-dependencies] proptest = "1.0" diff --git a/benches/hashmap.rs b/benches/hashmap.rs index 2ec45c8..8cca49e 100644 --- a/benches/hashmap.rs +++ b/benches/hashmap.rs @@ -159,6 +159,7 @@ where } fn remove(&mut self, k: &K) -> Option { + #[expect(clippy::if_same_then_else)] if self.remove_mut(k) { None // rpds doesn't return the removed value } else { diff --git a/benches/ordmap.rs b/benches/ordmap.rs index f9782a2..f126811 100644 --- a/benches/ordmap.rs +++ b/benches/ordmap.rs @@ -1,4 +1,5 @@ use criterion::{criterion_group, criterion_main, Bencher, Criterion}; +use equivalent::Comparable; use imbl::ordmap::OrdMap; use std::borrow::Borrow; use std::collections::BTreeMap; @@ -85,8 +86,7 @@ where fn get(&self, k: &Q) -> Option<&V> where - K: Borrow, - Q: Ord + ?Sized, + Q: Comparable + ?Sized, { self.get(k) } @@ -96,7 +96,7 @@ where } fn range<'a>(&'a self, range: std::ops::RangeFrom<&'a K>) -> Self::RangeIter<'a> { - self.range(range) + self.range::<_, K>(range) } fn is_empty(&self) -> bool { @@ -146,6 +146,7 @@ where } fn remove(&mut self, k: &K) -> Option { + #[expect(clippy::if_same_then_else)] if self.remove_mut(k) { None // rpds doesn't return the removed value } else { @@ -585,6 +586,7 @@ where }); } + #[expect(clippy::single_element_loop)] for size in &[1000] { group.bench_function(format!("remove_min_{}", size), |b| { bench_remove_min::(b, *size) diff --git a/src/hash/map.rs b/src/hash/map.rs index 2d49529..f5c4873 100644 --- a/src/hash/map.rs +++ b/src/hash/map.rs @@ -31,6 +31,7 @@ use std::mem; use std::ops::{Add, Index, IndexMut}; use archery::{SharedPointer, SharedPointerKind}; +use equivalent::Equivalent; use crate::nodes::hamt::{ hash_key, Drain as NodeDrain, HashBits, HashValue, Iter as NodeIter, IterMut as NodeIterMut, @@ -520,10 +521,9 @@ where /// ); /// ``` #[must_use] - pub fn get(&self, key: &BK) -> Option<&V> + pub fn get(&self, key: &Q) -> Option<&V> where - BK: Hash + Eq + ?Sized, - K: Borrow, + Q: Hash + Equivalent + ?Sized, { if let Some(root) = &self.root { root.get(hash_key(&self.hasher, key), 0, key) @@ -549,10 +549,9 @@ where /// ); /// ``` #[must_use] - pub fn get_key_value(&self, key: &BK) -> Option<(&K, &V)> + pub fn get_key_value(&self, key: &Q) -> Option<(&K, &V)> where - BK: Hash + Eq + ?Sized, - K: Borrow, + Q: Hash + Equivalent + ?Sized, { if let Some(root) = &self.root { root.get(hash_key(&self.hasher, key), 0, key) @@ -581,10 +580,9 @@ where /// ``` #[inline] #[must_use] - pub fn contains_key(&self, k: &BK) -> bool + pub fn contains_key(&self, k: &Q) -> bool where - BK: Hash + Eq + ?Sized, - K: Borrow, + Q: Hash + Equivalent + ?Sized, { self.get(k).is_some() } @@ -722,10 +720,9 @@ where /// ); /// ``` #[must_use] - pub fn get_mut(&mut self, key: &BK) -> Option<&mut V> + pub fn get_mut(&mut self, key: &Q) -> Option<&mut V> where - BK: Hash + Eq + ?Sized, - K: Borrow, + Q: Hash + Equivalent + ?Sized, { self.get_key_value_mut(key).map(|(_, v)| v) } @@ -746,14 +743,11 @@ where /// ); /// ``` #[must_use] - pub fn get_key_value_mut(&mut self, key: &BK) -> Option<(&K, &mut V)> + pub fn get_key_value_mut(&mut self, key: &Q) -> Option<(&K, &mut V)> where - BK: Hash + Eq + ?Sized, - K: Borrow, + Q: Hash + Equivalent + ?Sized, { - let Some(root) = self.root.as_mut() else { - return None; - }; + let root = self.root.as_mut()?; match SharedPointer::make_mut(root).get_mut(hash_key(&self.hasher, key), 0, key) { None => None, Some((key, value)) => Some((key, value)), @@ -811,10 +805,9 @@ where /// assert_eq!(None, map.remove(&789)); /// assert!(map.is_empty()); /// ``` - pub fn remove(&mut self, k: &BK) -> Option + pub fn remove(&mut self, k: &Q) -> Option where - BK: Hash + Eq + ?Sized, - K: Borrow, + Q: Hash + Equivalent + ?Sized, { self.remove_with_key(k).map(|(_, v)| v) } @@ -835,10 +828,9 @@ where /// assert_eq!(None, map.remove_with_key(&789)); /// assert!(map.is_empty()); /// ``` - pub fn remove_with_key(&mut self, k: &BK) -> Option<(K, V)> + pub fn remove_with_key(&mut self, k: &Q) -> Option<(K, V)> where - BK: Hash + Eq + ?Sized, - K: Borrow, + Q: Hash + Equivalent + ?Sized, { let Some(root) = &mut self.root else { return None; @@ -1001,10 +993,9 @@ where /// /// Time: O(log n) #[must_use] - pub fn without(&self, k: &BK) -> Self + pub fn without(&self, k: &Q) -> Self where - BK: Hash + Eq + ?Sized, - K: Borrow, + Q: Hash + Equivalent + ?Sized, { match self.extract_with_key(k) { None => self.clone(), @@ -1052,10 +1043,9 @@ where /// /// Time: O(log n) #[must_use] - pub fn extract(&self, k: &BK) -> Option<(V, Self)> + pub fn extract(&self, k: &Q) -> Option<(V, Self)> where - BK: Hash + Eq + ?Sized, - K: Borrow, + Q: Hash + Equivalent + ?Sized, { self.extract_with_key(k).map(|(_, v, m)| (v, m)) } @@ -1065,10 +1055,9 @@ where /// /// Time: O(log n) #[must_use] - pub fn extract_with_key(&self, k: &BK) -> Option<(K, V, Self)> + pub fn extract_with_key(&self, k: &Q) -> Option<(K, V, Self)> where - BK: Hash + Eq + ?Sized, - K: Borrow, + Q: Hash + Equivalent + ?Sized, { let mut out = self.clone(); out.remove_with_key(k).map(|(k, v)| (k, v, out)) @@ -1852,16 +1841,16 @@ where } } -impl Index<&BK> for GenericHashMap +impl Index<&Q> for GenericHashMap where - BK: Hash + Eq + ?Sized, - K: Hash + Eq + Borrow, + Q: Hash + Equivalent + ?Sized, + K: Hash + Eq, S: BuildHasher + Clone, P: SharedPointerKind, { type Output = V; - fn index(&self, key: &BK) -> &Self::Output { + fn index(&self, key: &Q) -> &Self::Output { match self.get(key) { None => panic!("HashMap::index: invalid key"), Some(value) => value, @@ -1869,15 +1858,15 @@ where } } -impl IndexMut<&BK> for GenericHashMap +impl IndexMut<&Q> for GenericHashMap where - BK: Hash + Eq + ?Sized, - K: Hash + Eq + Clone + Borrow, + Q: Hash + Equivalent + ?Sized, + K: Hash + Eq + Clone, V: Clone, S: BuildHasher + Clone, P: SharedPointerKind, { - fn index_mut(&mut self, key: &BK) -> &mut Self::Output { + fn index_mut(&mut self, key: &Q) -> &mut Self::Output { match self.get_mut(key) { None => panic!("HashMap::index_mut: invalid key"), Some(value) => value, @@ -2112,9 +2101,9 @@ impl AsRef> impl From<&GenericHashMap<&K, &V, SA, P1>> for GenericHashMap where - K: Hash + Eq + ToOwned + ?Sized, + K: Hash + Equivalent + ToOwned + ?Sized, V: ToOwned + ?Sized, - OK: Hash + Eq + Clone + Borrow, + OK: Hash + Eq + Clone, OV: Borrow + Clone, SA: BuildHasher + Clone, SB: BuildHasher + Default + Clone, diff --git a/src/hash/set.rs b/src/hash/set.rs index 50792ec..e24085b 100644 --- a/src/hash/set.rs +++ b/src/hash/set.rs @@ -30,6 +30,7 @@ use std::iter::{FromIterator, FusedIterator, Sum}; use std::ops::{Add, Deref, Mul}; use archery::{SharedPointer, SharedPointerKind}; +use equivalent::Equivalent; use crate::nodes::hamt::{hash_key, Drain as NodeDrain, HashValue, Iter as NodeIter, Node}; use crate::ordset::GenericOrdSet; @@ -321,13 +322,12 @@ where /// /// Time: O(log n) #[must_use] - pub fn contains(&self, a: &BA) -> bool + pub fn contains(&self, value: &Q) -> bool where - BA: Hash + Eq + ?Sized, - A: Borrow, + Q: Hash + Equivalent + ?Sized, { if let Some(root) = &self.root { - root.get(hash_key(&self.hasher, a), 0, a).is_some() + root.get(hash_key(&self.hasher, value), 0, value).is_some() } else { false } @@ -385,13 +385,12 @@ where /// Remove a value from a set if it exists. /// /// Time: O(log n) - pub fn remove(&mut self, a: &BA) -> Option + pub fn remove(&mut self, value: &Q) -> Option where - BA: Hash + Eq + ?Sized, - A: Borrow, + Q: Hash + Equivalent + ?Sized, { let root = SharedPointer::make_mut(self.root.get_or_insert_with(Default::default)); - let result = root.remove(hash_key(&self.hasher, a), 0, a); + let result = root.remove(hash_key(&self.hasher, value), 0, value); if result.is_some() { self.size -= 1; } @@ -427,13 +426,12 @@ where /// /// Time: O(log n) #[must_use] - pub fn without(&self, a: &BA) -> Self + pub fn without(&self, value: &Q) -> Self where - BA: Hash + Eq + ?Sized, - A: Borrow, + Q: Hash + Equivalent + ?Sized, { let mut out = self.clone(); - out.remove(a); + out.remove(value); out } @@ -466,7 +464,7 @@ where let old_root = root.clone(); let root = SharedPointer::make_mut(root); for (value, hash) in NodeIter::new(Some(&old_root), self.size) { - if !f(value) && root.remove(hash, 0, value).is_some() { + if !f(value) && root.remove(hash, 0, &**value).is_some() { self.size -= 1; } } @@ -889,8 +887,8 @@ where impl From<&GenericHashSet<&A, SA, P1>> for GenericHashSet where - A: ToOwned + Hash + Eq + ?Sized, - OA: Borrow + Hash + Eq + Clone, + A: ToOwned + Hash + Equivalent + ?Sized, + OA: Hash + Eq + Clone, SA: BuildHasher, SB: BuildHasher + Default + Clone, P1: SharedPointerKind, diff --git a/src/nodes/btree.rs b/src/nodes/btree.rs index ae9847b..0cfa07f 100644 --- a/src/nodes/btree.rs +++ b/src/nodes/btree.rs @@ -2,7 +2,6 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -use std::borrow::Borrow; use std::collections::VecDeque; use std::iter::FromIterator; use std::mem; @@ -10,6 +9,7 @@ use std::num::NonZeroUsize; use std::ops::{Bound, RangeBounds}; use archery::{SharedPointer, SharedPointerKind}; +use equivalent::Comparable; use imbl_sized_chunks::Chunk; pub(crate) use crate::config::ORD_CHUNK_SIZE as NODE_SIZE; @@ -263,10 +263,9 @@ pub(crate) struct Leaf { impl Node { /// Removes a key from the node or its children. /// Returns `true` if the node is underflowed and should be rebalanced. - pub(crate) fn remove(&mut self, key: &BK, removed: &mut Option<(K, V)>) -> bool + pub(crate) fn remove(&mut self, key: &Q, removed: &mut Option<(K, V)>) -> bool where - BK: Ord + ?Sized, - K: Borrow, + Q: Comparable + ?Sized, { match self { Node::Branch(branch) => SharedPointer::make_mut(branch).remove(key, removed), @@ -276,12 +275,11 @@ impl Node { } impl Branch { - pub(crate) fn remove(&mut self, key: &BK, removed: &mut Option<(K, V)>) -> bool + pub(crate) fn remove(&mut self, key: &Q, removed: &mut Option<(K, V)>) -> bool where - BK: Ord + ?Sized, - K: Borrow, + Q: Comparable + ?Sized, { - let i = slice_ext::binary_search_by(&self.keys, |k| k.borrow().cmp(key)) + let i = slice_ext::binary_search_by(&self.keys, |k| key.compare(k).reverse()) .map(|x| x + 1) .unwrap_or_else(|x| x); let rebalance = match &mut self.children { @@ -303,12 +301,11 @@ impl Branch { } impl Leaf { - pub(crate) fn remove(&mut self, key: &BK, removed: &mut Option<(K, V)>) -> bool + pub(crate) fn remove(&mut self, key: &Q, removed: &mut Option<(K, V)>) -> bool where - BK: Ord + ?Sized, - K: Borrow, + Q: Comparable + ?Sized, { - if let Ok(i) = slice_ext::binary_search_by(&self.keys, |(k, _)| k.borrow().cmp(key)) { + if let Ok(i) = slice_ext::binary_search_by(&self.keys, |(k, _)| key.compare(k).reverse()) { *removed = Some(self.keys.remove(i)); } // Underflow if the leaf is < 1/3 full. This relaxed underflow (vs. 1/2 full) is @@ -612,12 +609,11 @@ impl Leaf { } impl Branch { - pub(crate) fn lookup_mut(&mut self, key: &BK) -> Option<(&K, &mut V)> + pub(crate) fn lookup_mut(&mut self, key: &Q) -> Option<(&K, &mut V)> where - BK: Ord + ?Sized, - K: Borrow, + Q: Comparable + ?Sized, { - let i = slice_ext::binary_search_by(&self.keys, |k| k.borrow().cmp(key)) + let i = slice_ext::binary_search_by(&self.keys, |k| key.compare(k).reverse()) .map(|x| x + 1) .unwrap_or_else(|x| x); match &mut self.children { @@ -630,22 +626,20 @@ impl Branch { } impl Leaf { - pub(crate) fn lookup_mut(&mut self, key: &BK) -> Option<(&K, &mut V)> + pub(crate) fn lookup_mut(&mut self, key: &Q) -> Option<(&K, &mut V)> where - BK: Ord + ?Sized, - K: Borrow, + Q: Comparable + ?Sized, { let keys = &mut self.keys; - let i = slice_ext::binary_search_by(keys, |(k, _)| k.borrow().cmp(key)).ok()?; + let i = slice_ext::binary_search_by(keys, |(k, _)| key.compare(k).reverse()).ok()?; keys.get_mut(i).map(|(k, v)| (&*k, v)) } } impl Node { - pub(crate) fn lookup_mut(&mut self, key: &BK) -> Option<(&K, &mut V)> + pub(crate) fn lookup_mut(&mut self, key: &Q) -> Option<(&K, &mut V)> where - BK: Ord + ?Sized, - K: Borrow, + Q: Comparable + ?Sized, { match self { Node::Branch(branch) => SharedPointer::make_mut(branch).lookup_mut(key), @@ -689,14 +683,13 @@ impl Branch { } } } - pub(crate) fn lookup(&self, key: &BK) -> Option<&(K, V)> + pub(crate) fn lookup(&self, key: &Q) -> Option<&(K, V)> where - BK: Ord + ?Sized, - K: Borrow, + Q: Comparable + ?Sized, { let mut node = self; loop { - let i = slice_ext::binary_search_by(&node.keys, |k| k.borrow().cmp(key)) + let i = slice_ext::binary_search_by(&node.keys, |k| key.compare(k).reverse()) .map(|x| x + 1) .unwrap_or_else(|x| x); match &node.children { @@ -714,13 +707,12 @@ impl Leaf { fn max(&self) -> Option<&(K, V)> { self.keys.last() } - fn lookup(&self, key: &BK) -> Option<&(K, V)> + fn lookup(&self, key: &Q) -> Option<&(K, V)> where - BK: Ord + ?Sized, - K: Borrow, + Q: Comparable + ?Sized, { let keys = &self.keys; - let i = slice_ext::binary_search_by(keys, |(k, _)| k.borrow().cmp(key)).ok()?; + let i = slice_ext::binary_search_by(keys, |(k, _)| key.compare(k).reverse()).ok()?; keys.get(i) } } @@ -740,10 +732,9 @@ impl Node { } } - pub(crate) fn lookup(&self, key: &BK) -> Option<&(K, V)> + pub(crate) fn lookup(&self, key: &Q) -> Option<&(K, V)> where - BK: Ord + ?Sized, - K: Borrow, + Q: Comparable + ?Sized, { match self { Node::Branch(branch) => branch.lookup(key), @@ -896,11 +887,10 @@ pub(crate) struct Iter<'a, K, V, P: SharedPointerKind> { } impl<'a, K, V, P: SharedPointerKind> Iter<'a, K, V, P> { - pub(crate) fn new(root: Option<&'a Node>, len: usize, range: R) -> Self + pub(crate) fn new(root: Option<&'a Node>, len: usize, range: R) -> Self where - R: RangeBounds, - K: Borrow, - BK: Ord + ?Sized, + R: RangeBounds, + Q: Comparable + ?Sized, { let mut fwd = Cursor::empty(); let mut bwd = Cursor::empty(); @@ -1163,14 +1153,14 @@ impl<'a, K, V, P: SharedPointerKind> Cursor<'a, K, V, P> { } } - fn seek_to_key(&mut self, key: &BK, for_prev: bool) -> bool + fn seek_to_key(&mut self, key: &Q, for_prev: bool) -> bool where - BK: Ord + ?Sized, - K: Borrow, + Q: Comparable + ?Sized, { loop { if let Some((i, leaf)) = &mut self.leaf { - let search = slice_ext::binary_search_by(&leaf.keys, |(k, _)| k.borrow().cmp(key)); + let search = + slice_ext::binary_search_by(&leaf.keys, |(k, _)| key.compare(k).reverse()); *i = search.unwrap_or_else(|x| x); if for_prev { if search.is_err() { @@ -1184,7 +1174,7 @@ impl<'a, K, V, P: SharedPointerKind> Cursor<'a, K, V, P> { let Some((i, branch)) = self.stack.last_mut() else { return false; }; - *i = slice_ext::binary_search_by(&branch.keys, |k| k.borrow().cmp(key)) + *i = slice_ext::binary_search_by(&branch.keys, |k| key.compare(k).reverse()) .map(|x| x + 1) .unwrap_or_else(|x| x); let (i, branch) = (*i, *branch); diff --git a/src/nodes/hamt.rs b/src/nodes/hamt.rs index 0bb1c52..0679fc1 100644 --- a/src/nodes/hamt.rs +++ b/src/nodes/hamt.rs @@ -2,7 +2,6 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -use std::borrow::Borrow; use std::cell::UnsafeCell; use std::hash::{BuildHasher, Hash}; use std::iter::FusedIterator; @@ -12,6 +11,7 @@ use std::{fmt, mem, ptr}; use archery::{SharedPointer, SharedPointerKind}; use bitmaps::{Bits, BitsImpl}; +use equivalent::Equivalent; use imbl_sized_chunks::inline_array::InlineArray; use imbl_sized_chunks::sparse_chunk::{Iter as ChunkIter, IterMut as ChunkIterMut, SparseChunk}; @@ -204,10 +204,9 @@ where BitsImpl: Bits, { #[inline] - pub(crate) fn get(&self, hash: HashBits, key: &BK) -> Option<&A> + pub(crate) fn get(&self, hash: HashBits, key: &Q) -> Option<&A> where - BK: Eq + ?Sized, - A::Key: Borrow, + Q: Equivalent + ?Sized, { let (search, group) = Self::ctrl_hash_and_group(hash); let mut bitmap = group_find(&self.control[group], search); @@ -215,7 +214,7 @@ where while let Some(offset) = bitmap.first_index() { let index = group * GROUP_WIDTH + offset; let (ref value, value_hash) = self.data.get(index).unwrap(); - if hash_may_eq::(hash, *value_hash) && key == value.extract_key().borrow() { + if hash_may_eq::(hash, *value_hash) && key.equivalent(value.extract_key()) { return Some(value); } bitmap.set(offset, false); @@ -223,10 +222,9 @@ where None } - pub(crate) fn get_mut(&mut self, hash: HashBits, key: &BK) -> Option<&mut A> + pub(crate) fn get_mut(&mut self, hash: HashBits, key: &Q) -> Option<&mut A> where - BK: Eq + ?Sized, - A::Key: Borrow, + Q: Equivalent + ?Sized, { let (search, group) = Self::ctrl_hash_and_group(hash); let mut bitmap = group_find(&self.control[group], search); @@ -239,7 +237,7 @@ where #[allow(unsafe_code)] let this = unsafe { &mut *this }; let (ref mut value, value_hash) = this.data.get_mut(index).unwrap(); - if hash_may_eq::(hash, *value_hash) && key == value.extract_key().borrow() { + if hash_may_eq::(hash, *value_hash) && key.equivalent(value.extract_key()) { return Some(value); } bitmap.set(offset, false); @@ -247,10 +245,9 @@ where None } - pub(crate) fn remove(&mut self, hash: HashBits, key: &BK) -> Option + pub(crate) fn remove(&mut self, hash: HashBits, key: &Q) -> Option where - BK: Eq + ?Sized, - A::Key: Borrow, + Q: Equivalent + ?Sized, { let (search, group) = Self::ctrl_hash_and_group(hash); let mut bitmap = group_find(&self.control[group], search); @@ -258,7 +255,7 @@ where while let Some(offset) = bitmap.first_index() { let index = group * GROUP_WIDTH + offset; let (ref value, value_hash) = self.data.get(index).unwrap(); - if hash_may_eq::(hash, *value_hash) && key == value.extract_key().borrow() { + if hash_may_eq::(hash, *value_hash) && key.equivalent(value.extract_key()) { let mut ctrl_array = self.control[group].to_array(); ctrl_array[offset] = 0; self.control[group] = SimdGroup::from(ctrl_array); @@ -399,10 +396,9 @@ impl LargeSimdNode { } impl HamtNode { - pub(crate) fn get(&self, hash: HashBits, shift: usize, key: &BK) -> Option<&A> + pub(crate) fn get(&self, hash: HashBits, shift: usize, key: &Q) -> Option<&A> where - BK: Eq + ?Sized, - A::Key: Borrow, + Q: Equivalent + ?Sized, { let mut node = self; let mut shift = shift; @@ -425,7 +421,7 @@ impl HamtNode { } Entry::Value(ref value, value_hash) => { return if hash_may_eq::(hash, *value_hash) - && key == value.extract_key().borrow() + && key.equivalent(value.extract_key()) { Some(value) } else { @@ -442,10 +438,9 @@ impl HamtNode { #[cold] #[inline(always)] - fn get_terminal<'a, BK>(entry: &'a Entry, hash: HashBits, key: &BK) -> Option<&'a A> + fn get_terminal<'a, Q>(entry: &'a Entry, hash: HashBits, key: &Q) -> Option<&'a A> where - BK: Eq + ?Sized, - A::Key: Borrow, + Q: Equivalent + ?Sized, { match entry { Entry::SmallSimdNode(ref small) => small.get(hash, key), @@ -455,11 +450,10 @@ impl HamtNode { } } - pub(crate) fn get_mut(&mut self, hash: HashBits, shift: usize, key: &BK) -> Option<&mut A> + pub(crate) fn get_mut(&mut self, hash: HashBits, shift: usize, key: &Q) -> Option<&mut A> where A: Clone, - BK: Eq + ?Sized, - A::Key: Borrow, + Q: Equivalent + ?Sized, { let index = Self::mask(hash, shift) as usize; match self.data.get_mut(index) { @@ -473,7 +467,7 @@ impl HamtNode { SharedPointer::make_mut(large_ref).get_mut(hash, key) } Some(Entry::Value(ref mut value, value_hash)) => { - if hash_may_eq::(hash, *value_hash) && key == value.extract_key().borrow() { + if hash_may_eq::(hash, *value_hash) && key.equivalent(value.extract_key()) { Some(value) } else { None @@ -567,11 +561,10 @@ impl HamtNode { None } - pub(crate) fn remove(&mut self, hash: HashBits, shift: usize, key: &BK) -> Option + pub(crate) fn remove(&mut self, hash: HashBits, shift: usize, key: &Q) -> Option where A: Clone, - BK: Eq + ?Sized, - A::Key: Borrow, + Q: Equivalent + ?Sized, { let index = Self::mask(hash, shift) as usize; let removed; @@ -596,7 +589,7 @@ impl HamtNode { (large.len() == 1).then(|| large.pop_value()) } Entry::Value(value, value_hash) => { - if hash_may_eq::(hash, *value_hash) && key == value.extract_key().borrow() { + if hash_may_eq::(hash, *value_hash) && key.equivalent(value.extract_key()) { return self.data.remove(index).map(Entry::unwrap_value); } else { return None; @@ -683,25 +676,23 @@ impl CollisionNode { } #[cold] - fn get(&self, key: &BK) -> Option<&A> + fn get(&self, key: &Q) -> Option<&A> where - BK: Eq + ?Sized, - A::Key: Borrow, + Q: Equivalent + ?Sized, { self.data .iter() - .find(|&entry| key == entry.extract_key().borrow()) + .find(|&entry| key.equivalent(entry.extract_key())) } #[cold] - fn get_mut(&mut self, key: &BK) -> Option<&mut A> + fn get_mut(&mut self, key: &Q) -> Option<&mut A> where - BK: Eq + ?Sized, - A::Key: Borrow, + Q: Equivalent + ?Sized, { self.data .iter_mut() - .find(|entry| key == entry.extract_key().borrow()) + .find(|entry| key.equivalent(entry.extract_key())) } #[cold] @@ -716,13 +707,12 @@ impl CollisionNode { } #[cold] - fn remove(&mut self, key: &BK) -> Option + fn remove(&mut self, key: &Q) -> Option where - BK: Eq + ?Sized, - A::Key: Borrow, + Q: Equivalent + ?Sized, { for (index, item) in self.data.iter().enumerate() { - if key == item.extract_key().borrow() { + if key.equivalent(item.extract_key()) { return Some(self.data.swap_remove(index)); } } diff --git a/src/ord/map.rs b/src/ord/map.rs index ecac628..807a105 100644 --- a/src/ord/map.rs +++ b/src/ord/map.rs @@ -27,6 +27,7 @@ use std::mem; use std::ops::{Add, Bound, Index, IndexMut, RangeBounds}; use archery::{SharedPointer, SharedPointerKind}; +use equivalent::Comparable; use crate::hashmap::GenericHashMap; use crate::nodes::btree::{ @@ -256,17 +257,16 @@ where #[must_use] pub fn iter(&self) -> Iter<'_, K, V, P> { Iter { - it: NodeIter::new(self.root.as_ref(), self.size, ..), + it: NodeIter::new::<_, K>(self.root.as_ref(), self.size, ..), } } /// Create an iterator over a range of key/value pairs. #[must_use] - pub fn range(&self, range: R) -> RangedIter<'_, K, V, P> + pub fn range(&self, range: R) -> RangedIter<'_, K, V, P> where - R: RangeBounds, - K: Borrow, - BK: Ord + ?Sized, + R: RangeBounds, + Q: Comparable + ?Sized, { RangedIter { it: NodeIter::new(self.root.as_ref(), self.size, range), @@ -327,10 +327,9 @@ where /// ); /// ``` #[must_use] - pub fn get(&self, key: &BK) -> Option<&V> + pub fn get(&self, key: &Q) -> Option<&V> where - BK: Ord + ?Sized, - K: Borrow, + Q: Comparable + ?Sized, { self.root .as_ref() @@ -353,10 +352,9 @@ where /// ); /// ``` #[must_use] - pub fn get_key_value(&self, key: &BK) -> Option<(&K, &V)> + pub fn get_key_value(&self, key: &Q) -> Option<(&K, &V)> where - BK: Ord + ?Sized, - K: Borrow, + Q: Comparable + ?Sized, { self.root .as_ref() @@ -380,12 +378,11 @@ where /// assert_eq!(Some((&3, &3)), map.get_prev(&4)); /// ``` #[must_use] - pub fn get_prev(&self, key: &BK) -> Option<(&K, &V)> + pub fn get_prev(&self, key: &Q) -> Option<(&K, &V)> where - BK: Ord + ?Sized, - K: Borrow, + Q: Comparable + ?Sized, { - self.range((Bound::Unbounded, Bound::Included(key))) + self.range::<_, Q>((Bound::Unbounded, Bound::Included(key))) .next_back() } @@ -406,12 +403,12 @@ where /// assert_eq!(Some((&5, &5)), map.get_next(&4)); /// ``` #[must_use] - pub fn get_next(&self, key: &BK) -> Option<(&K, &V)> + pub fn get_next(&self, key: &Q) -> Option<(&K, &V)> where - BK: Ord + ?Sized, - K: Borrow, + Q: Comparable + ?Sized, { - self.range((Bound::Included(key), Bound::Unbounded)).next() + self.range::<_, Q>((Bound::Included(key), Bound::Unbounded)) + .next() } /// Test for the presence of a key in a map. @@ -432,10 +429,9 @@ where /// ); /// ``` #[must_use] - pub fn contains_key(&self, k: &BK) -> bool + pub fn contains_key(&self, k: &Q) -> bool where - BK: Ord + ?Sized, - K: Borrow, + Q: Comparable + ?Sized, { self.get(k).is_some() } @@ -571,10 +567,9 @@ where /// ); /// ``` #[must_use] - pub fn get_mut(&mut self, key: &BK) -> Option<&mut V> + pub fn get_mut(&mut self, key: &Q) -> Option<&mut V> where - BK: Ord + ?Sized, - K: Borrow, + Q: Comparable + ?Sized, { let root = self.root.as_mut()?; root.lookup_mut(key).map(|(_, v)| v) @@ -596,10 +591,9 @@ where /// ); /// ``` #[must_use] - pub fn get_key_value_mut(&mut self, key: &BK) -> Option<(&K, &mut V)> + pub fn get_key_value_mut(&mut self, key: &Q) -> Option<(&K, &mut V)> where - BK: Ord + ?Sized, - K: Borrow, + Q: Comparable + ?Sized, { self.root.as_mut()?.lookup_mut(key) } @@ -624,10 +618,9 @@ where /// assert_eq!(ordmap![1 => 1, 3 => 4, 5 => 5], map); /// ``` #[must_use] - pub fn get_prev_mut(&mut self, key: &BK) -> Option<(&K, &mut V)> + pub fn get_prev_mut(&mut self, key: &Q) -> Option<(&K, &mut V)> where - BK: Ord + ?Sized, - K: Borrow, + Q: Comparable + ?Sized, { let prev = self.get_prev(key)?.0.clone(); let root = self.root.as_mut()?; @@ -654,10 +647,9 @@ where /// assert_eq!(ordmap![1 => 1, 3 => 3, 5 => 4], map); /// ``` #[must_use] - pub fn get_next_mut(&mut self, key: &BK) -> Option<(&K, &mut V)> + pub fn get_next_mut(&mut self, key: &Q) -> Option<(&K, &mut V)> where - BK: Ord + ?Sized, - K: Borrow, + Q: Comparable + ?Sized, { let next = self.get_next(key)?.0.clone(); let root = self.root.as_mut()?; @@ -735,10 +727,9 @@ where /// /// [remove]: #method.remove #[inline] - pub fn remove(&mut self, k: &BK) -> Option + pub fn remove(&mut self, k: &Q) -> Option where - BK: Ord + ?Sized, - K: Borrow, + Q: Comparable + ?Sized, { self.remove_with_key(k).map(|(_, v)| v) } @@ -747,10 +738,9 @@ where /// the removed key and value. /// /// Time: O(log n) - pub fn remove_with_key(&mut self, k: &BK) -> Option<(K, V)> + pub fn remove_with_key(&mut self, k: &Q) -> Option<(K, V)> where - BK: Ord + ?Sized, - K: Borrow, + Q: Comparable + ?Sized, { let root = self.root.as_mut()?; let mut removed = None; @@ -884,10 +874,9 @@ where /// /// Time: O(log n) #[must_use] - pub fn without(&self, k: &BK) -> Self + pub fn without(&self, k: &Q) -> Self where - BK: Ord + ?Sized, - K: Borrow, + Q: Comparable + ?Sized, { self.extract(k) .map(|(_, m)| m) @@ -899,10 +888,9 @@ where /// /// Time: O(log n) #[must_use] - pub fn extract(&self, k: &BK) -> Option<(V, Self)> + pub fn extract(&self, k: &Q) -> Option<(V, Self)> where - BK: Ord + ?Sized, - K: Borrow, + Q: Comparable + ?Sized, { self.extract_with_key(k).map(|(_, v, m)| (v, m)) } @@ -912,10 +900,9 @@ where /// /// Time: O(log n) #[must_use] - pub fn extract_with_key(&self, k: &BK) -> Option<(K, V, Self)> + pub fn extract_with_key(&self, k: &Q) -> Option<(K, V, Self)> where - BK: Ord + ?Sized, - K: Borrow, + Q: Comparable + ?Sized, { let mut out = self.clone(); let result = out.remove_with_key(k); @@ -1373,10 +1360,9 @@ where /// /// The `split` mapping is discarded. #[must_use] - pub fn split(&self, split: &BK) -> (Self, Self) + pub fn split(&self, split: &Q) -> (Self, Self) where - BK: Ord + ?Sized, - K: Borrow, + Q: Comparable + ?Sized, { let (l, _, r) = self.split_lookup(split); (l, r) @@ -1388,15 +1374,14 @@ where /// /// Returns both the two maps and the value of `split`. #[must_use] - pub fn split_lookup(&self, split: &BK) -> (Self, Option, Self) + pub fn split_lookup(&self, split: &Q) -> (Self, Option, Self) where - BK: Ord + ?Sized, - K: Borrow, + Q: Comparable + ?Sized, { // TODO this is atrociously slow, got to be a better way self.iter().fold( (GenericOrdMap::new(), None, GenericOrdMap::new()), - |(l, m, r), (k, v)| match k.borrow().cmp(split) { + |(l, m, r), (k, v)| match split.compare(k).reverse() { Ordering::Less => (l.update(k.clone(), v.clone()), m, r), Ordering::Equal => (l, Some(v.clone()), r), Ordering::Greater => (l, m, r.update(k.clone(), v.clone())), @@ -1781,14 +1766,14 @@ where } } -impl Index<&BK> for GenericOrdMap +impl Index<&Q> for GenericOrdMap where - BK: Ord + ?Sized, - K: Ord + Borrow, + Q: Comparable + ?Sized, + K: Ord, { type Output = V; - fn index(&self, key: &BK) -> &Self::Output { + fn index(&self, key: &Q) -> &Self::Output { match self.get(key) { None => panic!("OrdMap::index: invalid key"), Some(value) => value, @@ -1796,14 +1781,14 @@ where } } -impl IndexMut<&BK> for GenericOrdMap +impl IndexMut<&Q> for GenericOrdMap where - BK: Ord + ?Sized, - K: Ord + Clone + Borrow, + Q: Comparable + ?Sized, + K: Ord + Clone, V: Clone, P: SharedPointerKind, { - fn index_mut(&mut self, key: &BK) -> &mut Self::Output { + fn index_mut(&mut self, key: &Q) -> &mut Self::Output { match self.get_mut(key) { None => panic!("OrdMap::index: invalid key"), Some(value) => value, @@ -2190,7 +2175,7 @@ impl From<&GenericOrdMap<&K, &V, P2>> for GenericOrdMap + ?Sized, V: ToOwned + ?Sized, - OK: Ord + Clone + Borrow, + OK: Ord + Clone, OV: Clone + Borrow, P1: SharedPointerKind, P2: SharedPointerKind, @@ -2206,7 +2191,6 @@ impl<'a, K, V, RK, RV, OK, OV, P> From<&'a [(RK, RV)]> for GenericOrdMap, V: Clone + From, - OK: Borrow, OV: Borrow, RK: ToOwned, RV: ToOwned, @@ -2230,11 +2214,10 @@ where } } -impl<'a, K: Ord, V, RK, RV, OK, OV, P> From<&'a Vec<(RK, RV)>> for GenericOrdMap +impl<'a, K, V, RK, RV, OK, OV, P> From<&'a Vec<(RK, RV)>> for GenericOrdMap where K: Ord + Clone + From, V: Clone + From, - OK: Borrow, OV: Borrow, RK: ToOwned, RV: ToOwned, @@ -2247,11 +2230,12 @@ where } } -impl From> for GenericOrdMap +impl From> for GenericOrdMap where K: Ord + Clone + From, V: Clone + From, P: SharedPointerKind, + RK: Eq + Hash, { fn from(m: collections::HashMap) -> GenericOrdMap { m.into_iter().collect() @@ -2262,7 +2246,6 @@ impl<'a, K, V, OK, OV, RK, RV, P> From<&'a collections::HashMap> for Gen where K: Ord + Clone + From, V: Clone + From, - OK: Borrow, OV: Borrow, RK: Hash + Eq + ToOwned, RV: ToOwned, @@ -2275,7 +2258,7 @@ where } } -impl From> for GenericOrdMap +impl From> for GenericOrdMap where K: Ord + Clone + From, V: Clone + From, @@ -2286,14 +2269,12 @@ where } } -impl<'a, K: Ord, V, RK, RV, OK, OV, P> From<&'a collections::BTreeMap> - for GenericOrdMap +impl<'a, K, V, RK, RV, OK, OV, P> From<&'a collections::BTreeMap> for GenericOrdMap where K: Ord + Clone + From, V: Clone + From, - OK: Borrow, OV: Borrow, - RK: Ord + ToOwned, + RK: Comparable + ToOwned, RV: ToOwned, P: SharedPointerKind, { @@ -2304,27 +2285,26 @@ where } } -impl< - K: Ord + Hash + Eq + Clone, - V: Clone, - S: BuildHasher + Clone, - P1: SharedPointerKind, - P2: SharedPointerKind, - > From> for GenericOrdMap +impl From> for GenericOrdMap +where + K: Ord + Hash + Eq + Clone, + V: Clone, + S: BuildHasher + Clone, + P1: SharedPointerKind, + P2: SharedPointerKind, { fn from(m: GenericHashMap) -> Self { m.into_iter().collect() } } -impl< - 'a, - K: Ord + Hash + Eq + Clone, - V: Clone, - S: BuildHasher + Clone, - P1: SharedPointerKind, - P2: SharedPointerKind, - > From<&'a GenericHashMap> for GenericOrdMap +impl<'a, K, V, S, P1, P2> From<&'a GenericHashMap> for GenericOrdMap +where + K: Ord + Hash + Eq + Clone, + V: Clone, + S: BuildHasher + Clone, + P1: SharedPointerKind, + P2: SharedPointerKind, { fn from(m: &'a GenericHashMap) -> Self { m.iter().map(|(k, v)| (k.clone(), v.clone())).collect() @@ -2569,33 +2549,37 @@ mod test { #[test] fn ranged_iter() { let map: OrdMap = ordmap![1=>2, 2=>3, 3=>4, 4=>5, 5=>6, 7=>8]; - let range: Vec<(i32, i32)> = map.range(..).map(|(k, v)| (*k, *v)).collect(); + let range: Vec<(i32, i32)> = map.range::<_, i32>(..).map(|(k, v)| (*k, *v)).collect(); assert_eq!(vec![(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (7, 8)], range); - let range: Vec<(i32, i32)> = map.range(..).rev().map(|(k, v)| (*k, *v)).collect(); + let range: Vec<(i32, i32)> = map + .range::<_, i32>(..) + .rev() + .map(|(k, v)| (*k, *v)) + .collect(); assert_eq!(vec![(7, 8), (5, 6), (4, 5), (3, 4), (2, 3), (1, 2)], range); - let range: Vec<(i32, i32)> = map.range(&2..&5).map(|(k, v)| (*k, *v)).collect(); + let range: Vec<(i32, i32)> = map.range(2..5).map(|(k, v)| (*k, *v)).collect(); assert_eq!(vec![(2, 3), (3, 4), (4, 5)], range); - let range: Vec<(i32, i32)> = map.range(&2..&5).rev().map(|(k, v)| (*k, *v)).collect(); + let range: Vec<(i32, i32)> = map.range(2..5).rev().map(|(k, v)| (*k, *v)).collect(); assert_eq!(vec![(4, 5), (3, 4), (2, 3)], range); - let range: Vec<(i32, i32)> = map.range(&3..).map(|(k, v)| (*k, *v)).collect(); + let range: Vec<(i32, i32)> = map.range(3..).map(|(k, v)| (*k, *v)).collect(); assert_eq!(vec![(3, 4), (4, 5), (5, 6), (7, 8)], range); - let range: Vec<(i32, i32)> = map.range(&3..).rev().map(|(k, v)| (*k, *v)).collect(); + let range: Vec<(i32, i32)> = map.range(3..).rev().map(|(k, v)| (*k, *v)).collect(); assert_eq!(vec![(7, 8), (5, 6), (4, 5), (3, 4)], range); let range: Vec<(i32, i32)> = map.range(..4).map(|(k, v)| (*k, *v)).collect(); assert_eq!(vec![(1, 2), (2, 3), (3, 4)], range); - let range: Vec<(i32, i32)> = map.range(..&4).rev().map(|(k, v)| (*k, *v)).collect(); + let range: Vec<(i32, i32)> = map.range(..4).rev().map(|(k, v)| (*k, *v)).collect(); assert_eq!(vec![(3, 4), (2, 3), (1, 2)], range); - let range: Vec<(i32, i32)> = map.range(..=&3).map(|(k, v)| (*k, *v)).collect(); + let range: Vec<(i32, i32)> = map.range(..=3).map(|(k, v)| (*k, *v)).collect(); assert_eq!(vec![(1, 2), (2, 3), (3, 4)], range); - let range: Vec<(i32, i32)> = map.range(..=&3).rev().map(|(k, v)| (*k, *v)).collect(); + let range: Vec<(i32, i32)> = map.range(..=3).rev().map(|(k, v)| (*k, *v)).collect(); assert_eq!(vec![(3, 4), (2, 3), (1, 2)], range); - let range: Vec<(i32, i32)> = map.range(..&6).map(|(k, v)| (*k, *v)).collect(); + let range: Vec<(i32, i32)> = map.range(..6).map(|(k, v)| (*k, *v)).collect(); assert_eq!(vec![(1, 2), (2, 3), (3, 4), (4, 5), (5, 6)], range); - let range: Vec<(i32, i32)> = map.range(..=&6).map(|(k, v)| (*k, *v)).collect(); + let range: Vec<(i32, i32)> = map.range(..=6).map(|(k, v)| (*k, *v)).collect(); assert_eq!(vec![(1, 2), (2, 3), (3, 4), (4, 5), (5, 6)], range); - assert_eq!(map.range(&2..&5).size_hint(), (0, Some(6))); - let mut iter = map.range(&2..&5); + assert_eq!(map.range(2..5).size_hint(), (0, Some(6))); + let mut iter = map.range(2..5); iter.next(); assert_eq!(iter.size_hint(), (0, Some(5))); } diff --git a/src/ord/set.rs b/src/ord/set.rs index 81afbe4..40d25f8 100644 --- a/src/ord/set.rs +++ b/src/ord/set.rs @@ -24,6 +24,7 @@ use std::iter::{FromIterator, FusedIterator, Sum}; use std::ops::{Add, Mul, RangeBounds}; use archery::SharedPointerKind; +use equivalent::Comparable; use super::map; use crate::hashset::GenericHashSet; @@ -215,11 +216,10 @@ where /// Create an iterator over a range inside the set. #[must_use] - pub fn range(&self, range: R) -> RangedIter<'_, A, P> + pub fn range(&self, range: R) -> RangedIter<'_, A, P> where - R: RangeBounds, - A: Borrow, - BA: Ord + ?Sized, + R: RangeBounds, + Q: Comparable + ?Sized, { RangedIter { it: self.map.range(range), @@ -259,12 +259,11 @@ where /// ``` #[inline] #[must_use] - pub fn contains(&self, a: &BA) -> bool + pub fn contains(&self, value: &Q) -> bool where - BA: Ord + ?Sized, - A: Borrow, + Q: Comparable + ?Sized, { - self.map.contains_key(a) + self.map.contains_key(value) } /// Returns a reference to the element in the set, if any, that is equal to the value. @@ -300,12 +299,11 @@ where /// assert_eq!(set.get(&0).unwrap().data, "Hello"); /// /// ``` - pub fn get(&self, k: &BK) -> Option<&A> + pub fn get(&self, value: &Q) -> Option<&A> where - BK: Ord + ?Sized, - A: Borrow, + Q: Comparable + ?Sized, { - self.map.get_key_value(k).map(|(k, _)| k) + self.map.get_key_value(value).map(|(k, _)| k) } /// Get the closest smaller value in a set to a given value. @@ -324,12 +322,11 @@ where /// assert_eq!(Some(&5), set.get_prev(&6)); /// ``` #[must_use] - pub fn get_prev(&self, k: &BK) -> Option<&A> + pub fn get_prev(&self, value: &Q) -> Option<&A> where - BK: Ord + ?Sized, - A: Borrow, + Q: Comparable + ?Sized, { - self.map.get_prev(k).map(|(k, _)| k) + self.map.get_prev(value).map(|(k, _)| k) } /// Get the closest larger value in a set to a given value. @@ -348,12 +345,11 @@ where /// assert_eq!(Some(&5), set.get_next(&4)); /// ``` #[must_use] - pub fn get_next(&self, k: &BK) -> Option<&A> + pub fn get_next(&self, value: &Q) -> Option<&A> where - BK: Ord + ?Sized, - A: Borrow, + Q: Comparable + ?Sized, { - self.map.get_next(k).map(|(k, _)| k) + self.map.get_next(value).map(|(k, _)| k) } /// Test whether a set is a subset of another set, meaning that @@ -427,12 +423,11 @@ where /// /// Time: O(log n) #[inline] - pub fn remove(&mut self, a: &BA) -> Option + pub fn remove(&mut self, value: &Q) -> Option where - BA: Ord + ?Sized, - A: Borrow, + Q: Comparable + ?Sized, { - self.map.remove_with_key(a).map(|(k, _)| k) + self.map.remove_with_key(value).map(|(k, _)| k) } /// Remove the smallest value from a set. @@ -481,13 +476,12 @@ where /// /// Time: O(log n) #[must_use] - pub fn without(&self, a: &BA) -> Self + pub fn without(&self, value: &Q) -> Self where - BA: Ord + ?Sized, - A: Borrow, + Q: Comparable + ?Sized, { let mut out = self.clone(); - out.remove(a); + out.remove(value); out } @@ -661,10 +655,9 @@ where /// /// Time: O(n) #[must_use] - pub fn split(self, split: &BA) -> (Self, Self) + pub fn split(self, split: &Q) -> (Self, Self) where - BA: Ord + ?Sized, - A: Borrow, + Q: Comparable + ?Sized, { let (left, _, right) = self.split_member(split); (left, right) @@ -680,16 +673,15 @@ where /// /// Time: O(n) #[must_use] - pub fn split_member(self, split: &BA) -> (Self, bool, Self) + pub fn split_member(self, split: &Q) -> (Self, bool, Self) where - BA: Ord + ?Sized, - A: Borrow, + Q: Comparable + ?Sized, { let mut left = Self::default(); let mut right = Self::default(); let mut present = false; for value in self { - match value.borrow().cmp(split) { + match split.compare(&value).reverse() { Ordering::Less => { left.insert(value); } @@ -1069,7 +1061,7 @@ where impl From<&GenericOrdSet<&A, P2>> for GenericOrdSet where A: ToOwned + Ord + ?Sized, - OA: Borrow + Ord + Clone, + OA: Ord + Clone, P1: SharedPointerKind, P2: SharedPointerKind, { @@ -1167,9 +1159,9 @@ mod test { #[test] fn ranged_iter() { let set = ordset![1, 2, 3, 4, 5]; - let range: Vec = set.range(..).cloned().collect(); + let range: Vec = set.range::<_, i32>(..).cloned().collect(); assert_eq!(vec![1, 2, 3, 4, 5], range); - let range: Vec = set.range(..).rev().cloned().collect(); + let range: Vec = set.range::<_, i32>(..).rev().cloned().collect(); assert_eq!(vec![5, 4, 3, 2, 1], range); let range: Vec = set.range(2..5).cloned().collect(); assert_eq!(vec![2, 3, 4], range); @@ -1201,12 +1193,12 @@ mod test { let range = 0..max; let expected: Vec = range.clone().collect(); let set: OrdSet = OrdSet::from_iter(range.clone()); - let result: Vec = set.range(..).cloned().collect(); + let result: Vec = set.range::<_, i32>(..).cloned().collect(); assert_eq!(expected, result); let expected: Vec = range.clone().rev().collect(); let set: OrdSet = OrdSet::from_iter(range); - let result: Vec = set.range(..).rev().cloned().collect(); + let result: Vec = set.range::<_, i32>(..).rev().cloned().collect(); assert_eq!(expected, result); } }