1 // Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10 
11 //! This module contains shims around the stdlib HashMap
12 //! that add fallible methods
13 //!
14 //! These methods are a lie. They are not actually fallible. This is just to make
15 //! it smooth to switch between hashmap impls in a codebase.
16 
17 use std::collections::HashMap as StdMap;
18 use std::collections::HashSet as StdSet;
19 use std::fmt;
20 use std::hash::{BuildHasher, Hash};
21 use std::ops::{Deref, DerefMut};
22 
23 pub use std::collections::hash_map::{Entry, Iter as MapIter, IterMut as MapIterMut, RandomState};
24 pub use std::collections::hash_set::{IntoIter as SetIntoIter, Iter as SetIter};
25 
26 #[derive(Clone)]
27 pub struct HashMap<K, V, S = RandomState>(StdMap<K, V, S>);
28 
29 use crate::FailedAllocationError;
30 
31 impl<K, V, S> Deref for HashMap<K, V, S> {
32     type Target = StdMap<K, V, S>;
deref(&self) -> &Self::Target33     fn deref(&self) -> &Self::Target {
34         &self.0
35     }
36 }
37 
38 impl<K, V, S> DerefMut for HashMap<K, V, S> {
deref_mut(&mut self) -> &mut Self::Target39     fn deref_mut(&mut self) -> &mut Self::Target {
40         &mut self.0
41     }
42 }
43 
44 impl<K, V, S> HashMap<K, V, S>
45 where
46     K: Eq + Hash,
47     S: BuildHasher,
48 {
49     #[inline]
try_with_hasher(hash_builder: S) -> Result<HashMap<K, V, S>, FailedAllocationError>50     pub fn try_with_hasher(hash_builder: S) -> Result<HashMap<K, V, S>, FailedAllocationError> {
51         Ok(HashMap(StdMap::with_hasher(hash_builder)))
52     }
53 
54     #[inline]
try_with_capacity_and_hasher( capacity: usize, hash_builder: S, ) -> Result<HashMap<K, V, S>, FailedAllocationError>55     pub fn try_with_capacity_and_hasher(
56         capacity: usize,
57         hash_builder: S,
58     ) -> Result<HashMap<K, V, S>, FailedAllocationError> {
59         Ok(HashMap(StdMap::with_capacity_and_hasher(
60             capacity,
61             hash_builder,
62         )))
63     }
64 
with_capacity_and_hasher(capacity: usize, hash_builder: S) -> HashMap<K, V, S>65     pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> HashMap<K, V, S> {
66         HashMap(StdMap::with_capacity_and_hasher(capacity, hash_builder))
67     }
68 
69     #[inline]
try_reserve(&mut self, additional: usize) -> Result<(), FailedAllocationError>70     pub fn try_reserve(&mut self, additional: usize) -> Result<(), FailedAllocationError> {
71         Ok(self.reserve(additional))
72     }
73 
try_shrink_to_fit(&mut self) -> Result<(), FailedAllocationError>74     pub fn try_shrink_to_fit(&mut self) -> Result<(), FailedAllocationError> {
75         Ok(self.shrink_to_fit())
76     }
77 
try_entry(&mut self, key: K) -> Result<Entry<K, V>, FailedAllocationError>78     pub fn try_entry(&mut self, key: K) -> Result<Entry<K, V>, FailedAllocationError> {
79         Ok(self.entry(key))
80     }
81 
82     #[inline]
try_insert(&mut self, k: K, v: V) -> Result<Option<V>, FailedAllocationError>83     pub fn try_insert(&mut self, k: K, v: V) -> Result<Option<V>, FailedAllocationError> {
84         Ok(self.insert(k, v))
85     }
86 }
87 
88 #[derive(Clone)]
89 pub struct HashSet<T, S = RandomState>(StdSet<T, S>);
90 
91 impl<T, S> Deref for HashSet<T, S> {
92     type Target = StdSet<T, S>;
deref(&self) -> &Self::Target93     fn deref(&self) -> &Self::Target {
94         &self.0
95     }
96 }
97 
98 impl<T, S> DerefMut for HashSet<T, S> {
deref_mut(&mut self) -> &mut Self::Target99     fn deref_mut(&mut self) -> &mut Self::Target {
100         &mut self.0
101     }
102 }
103 
104 impl<T: Hash + Eq> HashSet<T, RandomState> {
105     #[inline]
new() -> HashSet<T, RandomState>106     pub fn new() -> HashSet<T, RandomState> {
107         HashSet(StdSet::new())
108     }
109 
110     #[inline]
with_capacity(capacity: usize) -> HashSet<T, RandomState>111     pub fn with_capacity(capacity: usize) -> HashSet<T, RandomState> {
112         HashSet(StdSet::with_capacity(capacity))
113     }
114 }
115 
116 impl<T, S> HashSet<T, S>
117 where
118     T: Eq + Hash,
119     S: BuildHasher,
120 {
121     #[inline]
with_hasher(hasher: S) -> HashSet<T, S>122     pub fn with_hasher(hasher: S) -> HashSet<T, S> {
123         HashSet(StdSet::with_hasher(hasher))
124     }
125 
126     #[inline]
with_capacity_and_hasher(capacity: usize, hasher: S) -> HashSet<T, S>127     pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> HashSet<T, S> {
128         HashSet(StdSet::with_capacity_and_hasher(capacity, hasher))
129     }
130 
131     #[inline]
try_reserve(&mut self, additional: usize) -> Result<(), FailedAllocationError>132     pub fn try_reserve(&mut self, additional: usize) -> Result<(), FailedAllocationError> {
133         Ok(self.reserve(additional))
134     }
135 
136     #[inline]
try_shrink_to_fit(&mut self) -> Result<(), FailedAllocationError>137     pub fn try_shrink_to_fit(&mut self) -> Result<(), FailedAllocationError> {
138         Ok(self.shrink_to_fit())
139     }
140 
141     #[inline]
try_insert(&mut self, value: T) -> Result<bool, FailedAllocationError>142     pub fn try_insert(&mut self, value: T) -> Result<bool, FailedAllocationError> {
143         Ok(self.insert(value))
144     }
145 }
146 
147 // Pass through trait impls
148 // We can't derive these since the bounds are not obvious to the derive macro
149 
150 impl<K: Hash + Eq, V, S: BuildHasher + Default> Default for HashMap<K, V, S> {
default() -> Self151     fn default() -> Self {
152         HashMap(Default::default())
153     }
154 }
155 
156 impl<K, V, S> fmt::Debug for HashMap<K, V, S>
157 where
158     K: Eq + Hash + fmt::Debug,
159     V: fmt::Debug,
160     S: BuildHasher,
161 {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result162     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
163         self.0.fmt(f)
164     }
165 }
166 
167 impl<K, V, S> PartialEq for HashMap<K, V, S>
168 where
169     K: Eq + Hash,
170     V: PartialEq,
171     S: BuildHasher,
172 {
eq(&self, other: &HashMap<K, V, S>) -> bool173     fn eq(&self, other: &HashMap<K, V, S>) -> bool {
174         self.0.eq(&other.0)
175     }
176 }
177 
178 impl<K, V, S> Eq for HashMap<K, V, S>
179 where
180     K: Eq + Hash,
181     V: Eq,
182     S: BuildHasher,
183 {
184 }
185 
186 impl<'a, K, V, S> IntoIterator for &'a HashMap<K, V, S>
187 where
188     K: Eq + Hash,
189     S: BuildHasher,
190 {
191     type Item = (&'a K, &'a V);
192     type IntoIter = MapIter<'a, K, V>;
193 
into_iter(self) -> MapIter<'a, K, V>194     fn into_iter(self) -> MapIter<'a, K, V> {
195         self.0.iter()
196     }
197 }
198 
199 impl<'a, K, V, S> IntoIterator for &'a mut HashMap<K, V, S>
200 where
201     K: Eq + Hash,
202     S: BuildHasher,
203 {
204     type Item = (&'a K, &'a mut V);
205     type IntoIter = MapIterMut<'a, K, V>;
206 
into_iter(self) -> MapIterMut<'a, K, V>207     fn into_iter(self) -> MapIterMut<'a, K, V> {
208         self.0.iter_mut()
209     }
210 }
211 
212 impl<T: Eq + Hash, S: BuildHasher + Default> Default for HashSet<T, S> {
default() -> Self213     fn default() -> Self {
214         HashSet(Default::default())
215     }
216 }
217 
218 impl<T, S> fmt::Debug for HashSet<T, S>
219 where
220     T: Eq + Hash + fmt::Debug,
221     S: BuildHasher,
222 {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result223     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
224         self.0.fmt(f)
225     }
226 }
227 
228 impl<T, S> PartialEq for HashSet<T, S>
229 where
230     T: Eq + Hash,
231     S: BuildHasher,
232 {
eq(&self, other: &HashSet<T, S>) -> bool233     fn eq(&self, other: &HashSet<T, S>) -> bool {
234         self.0.eq(&other.0)
235     }
236 }
237 
238 impl<T, S> Eq for HashSet<T, S>
239 where
240     T: Eq + Hash,
241     S: BuildHasher,
242 {
243 }
244 
245 impl<'a, T, S> IntoIterator for &'a HashSet<T, S>
246 where
247     T: Eq + Hash,
248     S: BuildHasher,
249 {
250     type Item = &'a T;
251     type IntoIter = SetIter<'a, T>;
252 
into_iter(self) -> SetIter<'a, T>253     fn into_iter(self) -> SetIter<'a, T> {
254         self.0.iter()
255     }
256 }
257 
258 impl<T, S> IntoIterator for HashSet<T, S>
259 where
260     T: Eq + Hash,
261     S: BuildHasher,
262 {
263     type Item = T;
264     type IntoIter = SetIntoIter<T>;
265 
into_iter(self) -> SetIntoIter<T>266     fn into_iter(self) -> SetIntoIter<T> {
267         self.0.into_iter()
268     }
269 }
270