@@ -14,6 +14,7 @@ pub use self::Entry::*;
14
14
use self :: SearchResult :: * ;
15
15
use self :: VacantEntryState :: * ;
16
16
17
+ use borrow:: BorrowFrom ;
17
18
use clone:: Clone ;
18
19
use cmp:: { max, Eq , Equiv , PartialEq } ;
19
20
use default:: Default ;
@@ -142,7 +143,7 @@ impl DefaultResizePolicy {
142
143
// about the size of rust executables.
143
144
//
144
145
// Annotate exceedingly likely branches in `table::make_hash`
145
- // and `search_hashed_generic ` to reduce instruction cache pressure
146
+ // and `search_hashed ` to reduce instruction cache pressure
146
147
// and mispredictions once it becomes possible (blocked on issue #11092).
147
148
//
148
149
// Shrinking the table could simply reallocate in place after moving buckets
@@ -286,10 +287,10 @@ pub struct HashMap<K, V, H = RandomSipHasher> {
286
287
}
287
288
288
289
/// Search for a pre-hashed key.
289
- fn search_hashed_generic < K , V , M : Deref < RawTable < K , V > > > ( table : M ,
290
- hash : & SafeHash ,
291
- is_match: |& K | -> bool)
292
- -> SearchResult < K , V , M > {
290
+ fn search_hashed < K , V , M : Deref < RawTable < K , V > > > ( table : M ,
291
+ hash : & SafeHash ,
292
+ is_match: |& K | -> bool)
293
+ -> SearchResult < K , V , M > {
293
294
let size = table. size ( ) ;
294
295
let mut probe = Bucket :: new ( table, hash) ;
295
296
let ib = probe. index ( ) ;
@@ -325,11 +326,6 @@ fn search_hashed_generic<K, V, M: Deref<RawTable<K, V>>>(table: M,
325
326
TableRef ( probe. into_table ( ) )
326
327
}
327
328
328
- fn search_hashed < K : Eq , V , M : Deref < RawTable < K , V > > > ( table : M , hash : & SafeHash , k : & K )
329
- -> SearchResult < K , V , M > {
330
- search_hashed_generic ( table, hash, |k_| * k == * k_)
331
- }
332
-
333
329
fn pop_internal < K , V > ( starting_bucket : FullBucketMut < K , V > ) -> ( K , V ) {
334
330
let ( empty, retkey, retval) = starting_bucket. take ( ) ;
335
331
let mut gap = match empty. gap_peek ( ) {
@@ -432,26 +428,32 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
432
428
fn search_equiv < ' a , Sized ? Q : Hash < S > + Equiv < K > > ( & ' a self , q : & Q )
433
429
-> Option < FullBucketImm < ' a , K , V > > {
434
430
let hash = self . make_hash ( q) ;
435
- search_hashed_generic ( & self . table , & hash, |k| q. equiv ( k) ) . into_option ( )
431
+ search_hashed ( & self . table , & hash, |k| q. equiv ( k) ) . into_option ( )
436
432
}
437
433
438
434
fn search_equiv_mut < ' a , Sized ? Q : Hash < S > + Equiv < K > > ( & ' a mut self , q : & Q )
439
435
-> Option < FullBucketMut < ' a , K , V > > {
440
436
let hash = self . make_hash ( q) ;
441
- search_hashed_generic ( & mut self . table , & hash, |k| q. equiv ( k) ) . into_option ( )
437
+ search_hashed ( & mut self . table , & hash, |k| q. equiv ( k) ) . into_option ( )
442
438
}
443
439
444
440
/// Search for a key, yielding the index if it's found in the hashtable.
445
441
/// If you already have the hash for the key lying around, use
446
442
/// search_hashed.
447
- fn search < ' a > ( & ' a self , k : & K ) -> Option < FullBucketImm < ' a , K , V > > {
448
- let hash = self . make_hash ( k) ;
449
- search_hashed ( & self . table , & hash, k) . into_option ( )
443
+ fn search < ' a , Sized ? Q > ( & ' a self , q : & Q ) -> Option < FullBucketImm < ' a , K , V > >
444
+ where Q : BorrowFrom < K > + Eq + Hash < S >
445
+ {
446
+ let hash = self . make_hash ( q) ;
447
+ search_hashed ( & self . table , & hash, |k| q. eq ( BorrowFrom :: borrow_from ( k) ) )
448
+ . into_option ( )
450
449
}
451
450
452
- fn search_mut < ' a > ( & ' a mut self , k : & K ) -> Option < FullBucketMut < ' a , K , V > > {
453
- let hash = self . make_hash ( k) ;
454
- search_hashed ( & mut self . table , & hash, k) . into_option ( )
451
+ fn search_mut < ' a , Sized ? Q > ( & ' a mut self , q : & Q ) -> Option < FullBucketMut < ' a , K , V > >
452
+ where Q : BorrowFrom < K > + Eq + Hash < S >
453
+ {
454
+ let hash = self . make_hash ( q) ;
455
+ search_hashed ( & mut self . table , & hash, |k| q. eq ( BorrowFrom :: borrow_from ( k) ) )
456
+ . into_option ( )
455
457
}
456
458
457
459
// The caller should ensure that invariants by Robin Hood Hashing hold.
@@ -748,18 +750,14 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
748
750
}
749
751
}
750
752
751
- /// Return true if the map contains a value for the specified key,
752
- /// using equivalence.
753
- ///
754
- /// See [pop_equiv](#method.pop_equiv) for an extended example.
753
+ /// Deprecated: use `contains_key` and `BorrowFrom` instead.
754
+ #[ deprecated = "use contains_key and BorrowFrom instead" ]
755
755
pub fn contains_key_equiv < Sized ? Q : Hash < S > + Equiv < K > > ( & self , key : & Q ) -> bool {
756
756
self . search_equiv ( key) . is_some ( )
757
757
}
758
758
759
- /// Return the value corresponding to the key in the map, using
760
- /// equivalence.
761
- ///
762
- /// See [pop_equiv](#method.pop_equiv) for an extended example.
759
+ /// Deprecated: use `get` and `BorrowFrom` instead.
760
+ #[ deprecated = "use get and BorrowFrom instead" ]
763
761
pub fn find_equiv < ' a , Sized ? Q : Hash < S > + Equiv < K > > ( & ' a self , k : & Q ) -> Option < & ' a V > {
764
762
match self . search_equiv ( k) {
765
763
None => None ,
@@ -770,52 +768,8 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
770
768
}
771
769
}
772
770
773
- /// Remove an equivalent key from the map, returning the value at the
774
- /// key if the key was previously in the map.
775
- ///
776
- /// # Example
777
- ///
778
- /// This is a slightly silly example where we define the number's
779
- /// parity as the equivalence class. It is important that the
780
- /// values hash the same, which is why we implement `Hash`.
781
- ///
782
- /// ```
783
- /// use std::collections::HashMap;
784
- /// use std::hash::Hash;
785
- /// use std::hash::sip::SipState;
786
- ///
787
- /// #[deriving(Eq, PartialEq)]
788
- /// struct EvenOrOdd {
789
- /// num: uint
790
- /// };
791
- ///
792
- /// impl Hash for EvenOrOdd {
793
- /// fn hash(&self, state: &mut SipState) {
794
- /// let parity = self.num % 2;
795
- /// parity.hash(state);
796
- /// }
797
- /// }
798
- ///
799
- /// impl Equiv<EvenOrOdd> for EvenOrOdd {
800
- /// fn equiv(&self, other: &EvenOrOdd) -> bool {
801
- /// self.num % 2 == other.num % 2
802
- /// }
803
- /// }
804
- ///
805
- /// let mut map = HashMap::new();
806
- /// map.insert(EvenOrOdd { num: 3 }, "foo");
807
- ///
808
- /// assert!(map.contains_key_equiv(&EvenOrOdd { num: 1 }));
809
- /// assert!(!map.contains_key_equiv(&EvenOrOdd { num: 4 }));
810
- ///
811
- /// assert_eq!(map.find_equiv(&EvenOrOdd { num: 5 }), Some(&"foo"));
812
- /// assert_eq!(map.find_equiv(&EvenOrOdd { num: 2 }), None);
813
- ///
814
- /// assert_eq!(map.pop_equiv(&EvenOrOdd { num: 1 }), Some("foo"));
815
- /// assert_eq!(map.pop_equiv(&EvenOrOdd { num: 2 }), None);
816
- ///
817
- /// ```
818
- #[ experimental]
771
+ /// Deprecated: use `remove` and `BorrowFrom` instead.
772
+ #[ deprecated = "use remove and BorrowFrom instead" ]
819
773
pub fn pop_equiv < Sized ? Q : Hash < S > + Equiv < K > > ( & mut self , k : & Q ) -> Option < V > {
820
774
if self . table . size ( ) == 0 {
821
775
return None
@@ -1036,6 +990,10 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
1036
990
1037
991
/// Returns a reference to the value corresponding to the key.
1038
992
///
993
+ /// The key may be any borrowed form of the map's key type, but
994
+ /// `Hash` and `Eq` on the borrowed form *must* match those for
995
+ /// the key type.
996
+ ///
1039
997
/// # Example
1040
998
///
1041
999
/// ```
@@ -1047,7 +1005,9 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
1047
1005
/// assert_eq!(map.get(&2), None);
1048
1006
/// ```
1049
1007
#[ unstable = "matches collection reform specification, waiting for dust to settle" ]
1050
- pub fn get ( & self , k : & K ) -> Option < & V > {
1008
+ pub fn get < Sized ? Q > ( & self , k : & Q ) -> Option < & V >
1009
+ where Q : Hash < S > + Eq + BorrowFrom < K >
1010
+ {
1051
1011
self . search ( k) . map ( |bucket| {
1052
1012
let ( _, v) = bucket. into_refs ( ) ;
1053
1013
v
@@ -1056,6 +1016,10 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
1056
1016
1057
1017
/// Returns true if the map contains a value for the specified key.
1058
1018
///
1019
+ /// The key may be any borrowed form of the map's key type, but
1020
+ /// `Hash` and `Eq` on the borrowed form *must* match those for
1021
+ /// the key type.
1022
+ ///
1059
1023
/// # Example
1060
1024
///
1061
1025
/// ```
@@ -1067,7 +1031,9 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
1067
1031
/// assert_eq!(map.contains_key(&2), false);
1068
1032
/// ```
1069
1033
#[ unstable = "matches collection reform specification, waiting for dust to settle" ]
1070
- pub fn contains_key ( & self , k : & K ) -> bool {
1034
+ pub fn contains_key < Sized ? Q > ( & self , k : & Q ) -> bool
1035
+ where Q : Hash < S > + Eq + BorrowFrom < K >
1036
+ {
1071
1037
self . search ( k) . is_some ( )
1072
1038
}
1073
1039
@@ -1079,6 +1045,10 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
1079
1045
1080
1046
/// Returns a mutable reference to the value corresponding to the key.
1081
1047
///
1048
+ /// The key may be any borrowed form of the map's key type, but
1049
+ /// `Hash` and `Eq` on the borrowed form *must* match those for
1050
+ /// the key type.
1051
+ ///
1082
1052
/// # Example
1083
1053
///
1084
1054
/// ```
@@ -1093,7 +1063,9 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
1093
1063
/// assert_eq!(map[1], "b");
1094
1064
/// ```
1095
1065
#[ unstable = "matches collection reform specification, waiting for dust to settle" ]
1096
- pub fn get_mut ( & mut self , k : & K ) -> Option < & mut V > {
1066
+ pub fn get_mut < Sized ? Q > ( & mut self , k : & Q ) -> Option < & mut V >
1067
+ where Q : Hash < S > + Eq + BorrowFrom < K >
1068
+ {
1097
1069
match self . search_mut ( k) {
1098
1070
Some ( bucket) => {
1099
1071
let ( _, v) = bucket. into_mut_refs ( ) ;
@@ -1147,6 +1119,10 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
1147
1119
/// Removes a key from the map, returning the value at the key if the key
1148
1120
/// was previously in the map.
1149
1121
///
1122
+ /// The key may be any borrowed form of the map's key type, but
1123
+ /// `Hash` and `Eq` on the borrowed form *must* match those for
1124
+ /// the key type.
1125
+ ///
1150
1126
/// # Example
1151
1127
///
1152
1128
/// ```
@@ -1158,7 +1134,9 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
1158
1134
/// assert_eq!(map.remove(&1), None);
1159
1135
/// ```
1160
1136
#[ unstable = "matches collection reform specification, waiting for dust to settle" ]
1161
- pub fn remove ( & mut self , k : & K ) -> Option < V > {
1137
+ pub fn remove < Sized ? Q > ( & mut self , k : & Q ) -> Option < V >
1138
+ where Q : Hash < S > + Eq + BorrowFrom < K >
1139
+ {
1162
1140
if self . table . size ( ) == 0 {
1163
1141
return None
1164
1142
}
@@ -1271,16 +1249,20 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> Default for HashMap<K, V, H>
1271
1249
}
1272
1250
}
1273
1251
1274
- impl < K : Eq + Hash < S > , V , S , H : Hasher < S > > Index < K , V > for HashMap < K , V , H > {
1252
+ impl < K : Hash < S > + Eq , Sized ? Q , V , S , H : Hasher < S > > Index < Q , V > for HashMap < K , V , H >
1253
+ where Q : BorrowFrom < K > + Hash < S > + Eq
1254
+ {
1275
1255
#[ inline]
1276
- fn index < ' a > ( & ' a self , index : & K ) -> & ' a V {
1256
+ fn index < ' a > ( & ' a self , index : & Q ) -> & ' a V {
1277
1257
self . get ( index) . expect ( "no entry found for key" )
1278
1258
}
1279
1259
}
1280
1260
1281
- impl < K : Eq + Hash < S > , V , S , H : Hasher < S > > IndexMut < K , V > for HashMap < K , V , H > {
1261
+ impl < K : Hash < S > + Eq , Sized ? Q , V , S , H : Hasher < S > > IndexMut < Q , V > for HashMap < K , V , H >
1262
+ where Q : BorrowFrom < K > + Hash < S > + Eq
1263
+ {
1282
1264
#[ inline]
1283
- fn index_mut < ' a > ( & ' a mut self , index : & K ) -> & ' a mut V {
1265
+ fn index_mut < ' a > ( & ' a mut self , index : & Q ) -> & ' a mut V {
1284
1266
match self . get_mut ( index) {
1285
1267
Some ( v) => v,
1286
1268
None => panic ! ( "no entry found for key" )
0 commit comments