@@ -306,14 +306,14 @@ where
306
306
& mut self ,
307
307
hash : u64 ,
308
308
eq : impl FnMut ( & T ) -> bool ,
309
- ) -> Result < OccupiedEntry < ' _ , T , A > , & mut Self > {
309
+ ) -> Result < OccupiedEntry < ' _ , T , A > , AbsentEntry < ' _ , T , A > > {
310
310
match self . raw . find ( hash, eq) {
311
311
Some ( bucket) => Ok ( OccupiedEntry {
312
312
hash,
313
313
bucket,
314
314
table : self ,
315
315
} ) ,
316
- None => Err ( self ) ,
316
+ None => Err ( AbsentEntry { table : self } ) ,
317
317
}
318
318
}
319
319
@@ -1763,6 +1763,70 @@ where
1763
1763
}
1764
1764
}
1765
1765
1766
+ /// Type representing the absence of an entry, as returned by [`HashTable::find_entry`].
1767
+ ///
1768
+ /// This type only exists due to [limitations] in Rust's NLL borrow checker. In
1769
+ /// the future, `find_entry` will return an `Option<OccupiedEntry>` and this
1770
+ /// type will be removed.
1771
+ ///
1772
+ /// [limitations]: https://smallcultfollowing.com/babysteps/blog/2018/06/15/mir-based-borrow-check-nll-status-update/#polonius
1773
+ /// # Examples
1774
+ ///
1775
+ /// ```
1776
+ /// # #[cfg(feature = "nightly")]
1777
+ /// # fn test() {
1778
+ /// use ahash::AHasher;
1779
+ /// use hashbrown::hash_table::{AbsentEntry, Entry, HashTable};
1780
+ /// use std::hash::{BuildHasher, BuildHasherDefault};
1781
+ ///
1782
+ /// let mut table: HashTable<&str> = HashTable::new();
1783
+ /// let hasher = BuildHasherDefault::<AHasher>::default();
1784
+ /// let hasher = |val: &_| hasher.hash_one(val);
1785
+ ///
1786
+ /// let entry_v: AbsentEntry<_, _> = table.find_entry(hasher(&"a"), |&x| x == "a").unwrap_err();
1787
+ /// entry_v
1788
+ /// .into_table()
1789
+ /// .insert_unchecked(hasher(&"a"), "a", hasher);
1790
+ /// assert!(table.find(hasher(&"a"), |&x| x == "a").is_some() && table.len() == 1);
1791
+ ///
1792
+ /// // Nonexistent key (insert)
1793
+ /// match table.entry(hasher(&"b"), |&x| x == "b", hasher) {
1794
+ /// Entry::Vacant(view) => {
1795
+ /// view.insert("b");
1796
+ /// }
1797
+ /// Entry::Occupied(_) => unreachable!(),
1798
+ /// }
1799
+ /// assert!(table.find(hasher(&"b"), |&x| x == "b").is_some() && table.len() == 2);
1800
+ /// # }
1801
+ /// # fn main() {
1802
+ /// # #[cfg(feature = "nightly")]
1803
+ /// # test()
1804
+ /// # }
1805
+ /// ```
1806
+ pub struct AbsentEntry < ' a , T , A = Global >
1807
+ where
1808
+ A : Allocator ,
1809
+ {
1810
+ table : & ' a mut HashTable < T , A > ,
1811
+ }
1812
+
1813
+ impl < T : fmt:: Debug , A : Allocator > fmt:: Debug for AbsentEntry < ' _ , T , A > {
1814
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1815
+ f. write_str ( "AbsentEntry" )
1816
+ }
1817
+ }
1818
+
1819
+ impl < ' a , T , A > AbsentEntry < ' a , T , A >
1820
+ where
1821
+ A : Allocator ,
1822
+ {
1823
+ /// Converts the AbsentEntry into a mutable reference to the underlying
1824
+ /// table.
1825
+ pub fn into_table ( self ) -> & ' a mut HashTable < T , A > {
1826
+ self . table
1827
+ }
1828
+ }
1829
+
1766
1830
/// An iterator over the entries of a `HashTable` in arbitrary order.
1767
1831
/// The iterator element type is `&'a T`.
1768
1832
///
0 commit comments