Skip to content

Commit 886c2f4

Browse files
committed
make ArrayMap independent of the RawTable by introducing ArrayMapFacade
The main motivation for this change is to be able to have an array based equivalent to `HashMap` and `IndexMap` without having to duplicate the code. The name `ArrayMapFacade` comes from the `stable_vec` crate, which has a `StableVecFacade`
1 parent fe00e5a commit 886c2f4

File tree

2 files changed

+92
-56
lines changed

2 files changed

+92
-56
lines changed

src/array_map.rs

Lines changed: 77 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use core::borrow::Borrow;
22
use core::hash::{BuildHasher, Hash};
3+
use core::marker::PhantomData;
34
use core::ops::Index;
45
use core::{fmt, mem};
56

@@ -8,26 +9,30 @@ use crate::errors::{CapacityError, RescaleError, UnavailableMutError};
89
use crate::ext::{TryExtend, TryFromIterator};
910
use crate::iter::{Drain, DrainFilter, Iter, IterMut, Keys, Values, ValuesMut};
1011
use crate::occupied::OccupiedEntry;
11-
use crate::raw::{ArrayTable, RawEntryBuilder, RawTable};
12+
use crate::raw::{ArrayTable, RawEntryBuilder, RawTable, RawTableIter};
1213
use crate::utils;
1314
use crate::vacant::VacantEntry;
1415

15-
/// Default hasher for [`ArrayMap`].
16+
/// Default hasher for [`ArrayMapFacade`].
1617
#[cfg(feature = "ahash")]
1718
pub type DefaultHashBuilder = core::hash::BuildHasherDefault<ahash::AHasher>;
1819
/// Dummy default hasher
1920
#[cfg(not(feature = "ahash"))]
2021
pub enum DefaultHashBuilder {}
2122

23+
pub type ArrayMap<K, V, const N: usize, B = DefaultHashBuilder> =
24+
ArrayMapFacade<K, V, ArrayTable<(K, V), N>, B>;
25+
2226
#[derive(Copy, Clone)]
23-
pub struct ArrayMap<K, V, const N: usize, B = DefaultHashBuilder> {
24-
table: ArrayTable<(K, V), N>,
27+
pub struct ArrayMapFacade<K, V, R: RawTable<(K, V)>, B = DefaultHashBuilder> {
28+
table: R,
2529
build_hasher: B,
30+
_p: PhantomData<(K, V)>,
2631
}
2732

2833
#[cfg(feature = "ahash")]
29-
impl<K, V, const N: usize> ArrayMap<K, V, N, DefaultHashBuilder> {
30-
/// Creates an empty [`ArrayMap`] with the [`DefaultHashBuilder`].
34+
impl<K, V, R: RawTable<(K, V)> + Default> ArrayMapFacade<K, V, R, DefaultHashBuilder> {
35+
/// Creates an empty [`ArrayMapFacade`] with the [`DefaultHashBuilder`].
3136
///
3237
/// # Examples
3338
///
@@ -42,8 +47,8 @@ impl<K, V, const N: usize> ArrayMap<K, V, N, DefaultHashBuilder> {
4247
}
4348
}
4449

45-
impl<K, V, const N: usize, B: BuildHasher> ArrayMap<K, V, N, B> {
46-
/// Creates an empty [`ArrayMap`] with the provided [`BuildHasher`].
50+
impl<K, V, R: RawTable<(K, V)> + Default, B: BuildHasher> ArrayMapFacade<K, V, R, B> {
51+
/// Creates an empty [`ArrayMapFacade`] with the provided [`BuildHasher`].
4752
///
4853
/// # Note
4954
///
@@ -66,7 +71,7 @@ impl<K, V, const N: usize, B: BuildHasher> ArrayMap<K, V, N, B> {
6671
Self::with_build_hasher(build_hasher)
6772
}
6873

69-
/// Creates an empty [`ArrayMap`] with the provided [`BuildHasher`].
74+
/// Creates an empty [`ArrayMapFacade`] with the provided [`BuildHasher`].
7075
///
7176
/// # Examples
7277
///
@@ -81,11 +86,14 @@ impl<K, V, const N: usize, B: BuildHasher> ArrayMap<K, V, N, B> {
8186
#[doc(alias("with_hasher"))]
8287
pub fn with_build_hasher(build_hasher: B) -> Self {
8388
Self {
84-
table: ArrayTable::default(),
89+
table: R::default(),
8590
build_hasher,
91+
_p: PhantomData,
8692
}
8793
}
94+
}
8895

96+
impl<K, V, R: RawTable<(K, V)>, B: BuildHasher> ArrayMapFacade<K, V, R, B> {
8997
/// Returns the number of elements the map can hold in total.
9098
///
9199
/// The returned value, will be equal to the const generic `N`.
@@ -103,7 +111,7 @@ impl<K, V, const N: usize, B: BuildHasher> ArrayMap<K, V, N, B> {
103111
/// ```
104112
#[must_use]
105113
pub fn capacity(&self) -> usize {
106-
N
114+
self.table.capacity()
107115
}
108116

109117
/// Returns the number of elements in the map.
@@ -164,9 +172,10 @@ impl<K, V, const N: usize, B: BuildHasher> ArrayMap<K, V, N, B> {
164172
}
165173
}
166174

167-
impl<K, V, B, const N: usize> ArrayMap<K, V, N, B>
175+
impl<K, V, R, B> ArrayMapFacade<K, V, R, B>
168176
where
169177
K: Eq + Hash,
178+
R: RawTable<(K, V)>,
170179
B: BuildHasher,
171180
{
172181
/// Gets the given key's corresponding entry in the map for in-place
@@ -192,10 +201,7 @@ where
192201
/// assert_eq!(letters.get(&'y'), None);
193202
/// # Ok::<_, array_map::CapacityError>(())
194203
/// ```
195-
pub fn entry(
196-
&mut self,
197-
key: K,
198-
) -> Result<Entry<'_, K, V, ArrayTable<(K, V), N>, B>, CapacityError> {
204+
pub fn entry(&mut self, key: K) -> Result<Entry<'_, K, V, R, B>, CapacityError> {
199205
let hash = utils::make_hash::<K, K, B>(&self.build_hasher, &key);
200206

201207
if let Some(ident) = self.table.find(hash, |(k, _)| k.eq(&key)) {
@@ -639,7 +645,7 @@ where
639645
///
640646
/// assert_eq!(drained, [None, None, None, Some(("rust", "rost")),]);
641647
/// ```
642-
pub fn drain_filter<F>(&mut self, f: F) -> DrainFilter<'_, K, V, F, ArrayTable<(K, V), N>, B>
648+
pub fn drain_filter<F>(&mut self, f: F) -> DrainFilter<'_, K, V, F, R, B>
643649
where
644650
F: FnMut(&K, &mut V) -> bool,
645651
{
@@ -672,7 +678,7 @@ where
672678
/// ]
673679
/// );
674680
/// ```
675-
pub fn drain(&mut self) -> Drain<'_, K, V, ArrayTable<(K, V), N>, B> {
681+
pub fn drain(&mut self) -> Drain<'_, K, V, R, B> {
676682
Drain::new(&mut self.table, &self.build_hasher)
677683
}
678684

@@ -701,11 +707,9 @@ where
701707
/// assert_eq!(rescaled.get(&'a'), Some(&('a' as u32)));
702708
/// # Ok::<_, array_map::CapacityError>(())
703709
/// ```
704-
pub fn try_rescale<const M: usize>(
705-
mut self,
706-
) -> Result<ArrayMap<K, V, M, B>, RescaleError<N, M>> {
710+
pub fn try_rescale<const M: usize>(mut self) -> Result<ArrayMap<K, V, M, B>, RescaleError<M>> {
707711
if self.len() >= M {
708-
return Err(RescaleError::new(self.len()));
712+
return Err(RescaleError::new(self.len(), self.capacity()));
709713
}
710714

711715
let mut result = ArrayMap::with_build_hasher(self.build_hasher);
@@ -778,16 +782,20 @@ where
778782
/// Immutable raw entries have a very limited use; you might instead want to
779783
/// use `ArrayMap::raw_entry_mut`.
780784
#[must_use]
781-
pub fn raw_entry(&self) -> RawEntryBuilder<'_, K, V, ArrayTable<(K, V), N>, B> {
785+
pub fn raw_entry(&self) -> RawEntryBuilder<'_, K, V, R, B> {
782786
RawEntryBuilder::new(&self.table, &self.build_hasher)
783787
}
784788

785-
pub(crate) fn into_parts(self) -> (B, <ArrayTable<(K, V), N> as IntoIterator>::IntoIter) {
789+
pub(crate) fn into_parts(self) -> (B, <R as IntoIterator>::IntoIter) {
786790
(self.build_hasher, self.table.into_iter())
787791
}
788792
}
789793

790-
impl<K, V, B: BuildHasher, const N: usize> ArrayMap<K, V, N, B> {
794+
impl<K, V, R, B> ArrayMapFacade<K, V, R, B>
795+
where
796+
R: RawTableIter<(K, V)>,
797+
B: BuildHasher,
798+
{
791799
/// Returns an iterator iterating over the immutable entries of the map.
792800
///
793801
/// # Examples
@@ -816,7 +824,7 @@ impl<K, V, B: BuildHasher, const N: usize> ArrayMap<K, V, N, B> {
816824
/// );
817825
/// # Ok::<_, CollectArrayError>(())
818826
/// ```
819-
pub fn iter(&self) -> Iter<'_, K, V, ArrayTable<(K, V), N>> {
827+
pub fn iter(&self) -> Iter<'_, K, V, R> {
820828
Iter::new(&self.table)
821829
}
822830

@@ -850,7 +858,7 @@ impl<K, V, B: BuildHasher, const N: usize> ArrayMap<K, V, N, B> {
850858
/// }
851859
/// );
852860
/// ```
853-
pub fn iter_mut(&mut self) -> IterMut<'_, K, V, ArrayTable<(K, V), N>> {
861+
pub fn iter_mut(&mut self) -> IterMut<'_, K, V, R> {
854862
IterMut::new(&mut self.table)
855863
}
856864

@@ -876,7 +884,7 @@ impl<K, V, B: BuildHasher, const N: usize> ArrayMap<K, V, N, B> {
876884
/// assert_eq!(keys, [&"good bye", &"good night", &"hello",]);
877885
/// # Ok::<_, CollectArrayError>(())
878886
/// ```
879-
pub fn keys(&self) -> Keys<'_, K, V, ArrayTable<(K, V), N>> {
887+
pub fn keys(&self) -> Keys<'_, K, V, R> {
880888
Keys::new(self.iter())
881889
}
882890

@@ -902,7 +910,7 @@ impl<K, V, B: BuildHasher, const N: usize> ArrayMap<K, V, N, B> {
902910
/// assert_eq!(values, [&"au revoir", &"bonne nuit", &"salut",]);
903911
/// # Ok::<_, CollectArrayError>(())
904912
/// ```
905-
pub fn values(&self) -> Values<'_, K, V, ArrayTable<(K, V), N>> {
913+
pub fn values(&self) -> Values<'_, K, V, R> {
906914
Values::new(self.iter())
907915
}
908916

@@ -937,15 +945,16 @@ impl<K, V, B: BuildHasher, const N: usize> ArrayMap<K, V, N, B> {
937945
/// }
938946
/// );
939947
/// ```
940-
pub fn values_mut(&mut self) -> ValuesMut<'_, K, V, ArrayTable<(K, V), N>> {
948+
pub fn values_mut(&mut self) -> ValuesMut<'_, K, V, R> {
941949
ValuesMut::new(self.iter_mut())
942950
}
943951
}
944952

945-
impl<K, Q: ?Sized, V, B, const N: usize> Index<&Q> for ArrayMap<K, V, N, B>
953+
impl<K, Q: ?Sized, V, R, B> Index<&Q> for ArrayMapFacade<K, V, R, B>
946954
where
947955
K: Eq + Hash + Borrow<Q>,
948956
Q: Eq + Hash,
957+
R: RawTable<(K, V)>,
949958
B: BuildHasher,
950959
{
951960
type Output = V;
@@ -960,53 +969,72 @@ where
960969
}
961970
}
962971

963-
impl<'a, K, V, B: BuildHasher, const N: usize> IntoIterator for &'a ArrayMap<K, V, N, B> {
964-
type IntoIter = Iter<'a, K, V, ArrayTable<(K, V), N>>;
972+
impl<'a, K, V, R, B> IntoIterator for &'a ArrayMapFacade<K, V, R, B>
973+
where
974+
R: RawTableIter<(K, V)>,
975+
B: BuildHasher,
976+
{
977+
type IntoIter = Iter<'a, K, V, R>;
965978
type Item = (&'a K, &'a V);
966979

967980
fn into_iter(self) -> Self::IntoIter {
968981
self.iter()
969982
}
970983
}
971984

972-
impl<'a, K, V, B: BuildHasher, const N: usize> IntoIterator for &'a mut ArrayMap<K, V, N, B> {
973-
type IntoIter = IterMut<'a, K, V, ArrayTable<(K, V), N>>;
985+
impl<'a, K, V, R, B> IntoIterator for &'a mut ArrayMapFacade<K, V, R, B>
986+
where
987+
R: RawTableIter<(K, V)>,
988+
B: BuildHasher,
989+
{
990+
type IntoIter = IterMut<'a, K, V, R>;
974991
type Item = (&'a K, &'a mut V);
975992

976993
fn into_iter(self) -> Self::IntoIter {
977994
self.iter_mut()
978995
}
979996
}
980997

981-
impl<K, V, B: BuildHasher, const N: usize> IntoIterator for ArrayMap<K, V, N, B> {
982-
type IntoIter = <ArrayTable<(K, V), N> as IntoIterator>::IntoIter;
998+
impl<K, V, R, B> IntoIterator for ArrayMapFacade<K, V, R, B>
999+
where
1000+
R: RawTable<(K, V)>,
1001+
B: BuildHasher,
1002+
{
1003+
type IntoIter = <R as IntoIterator>::IntoIter;
9831004
type Item = (K, V);
9841005

9851006
fn into_iter(self) -> Self::IntoIter {
9861007
self.table.into_iter()
9871008
}
9881009
}
9891010

990-
impl<K, V, B: BuildHasher + Default, const N: usize> Default for ArrayMap<K, V, N, B> {
1011+
impl<K, V, R, B> Default for ArrayMapFacade<K, V, R, B>
1012+
where
1013+
R: RawTable<(K, V)> + Default,
1014+
B: BuildHasher + Default,
1015+
{
9911016
fn default() -> Self {
9921017
Self::with_hasher(B::default())
9931018
}
9941019
}
9951020

996-
impl<K, V, B: BuildHasher, const N: usize> fmt::Debug for ArrayMap<K, V, N, B>
1021+
impl<K, V, R, B> fmt::Debug for ArrayMapFacade<K, V, R, B>
9971022
where
9981023
K: fmt::Debug,
9991024
V: fmt::Debug,
1025+
R: RawTableIter<(K, V)>,
1026+
B: BuildHasher,
10001027
{
10011028
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10021029
f.debug_map().entries(self.iter()).finish()
10031030
}
10041031
}
10051032

1006-
impl<K, V, B, const N: usize> PartialEq<Self> for ArrayMap<K, V, N, B>
1033+
impl<K, V, R, B> PartialEq<Self> for ArrayMapFacade<K, V, R, B>
10071034
where
10081035
K: Eq + Hash,
10091036
V: PartialEq,
1037+
R: RawTableIter<(K, V)>,
10101038
B: BuildHasher,
10111039
{
10121040
fn eq(&self, other: &Self) -> bool {
@@ -1019,23 +1047,25 @@ where
10191047
}
10201048
}
10211049

1022-
impl<K, V, B, const N: usize> Eq for ArrayMap<K, V, N, B>
1050+
impl<K, V, R, B> Eq for ArrayMapFacade<K, V, R, B>
10231051
where
10241052
K: Eq + Hash,
10251053
V: PartialEq,
1054+
R: RawTableIter<(K, V)>,
10261055
B: BuildHasher,
10271056
{
10281057
}
10291058

1030-
impl<K, V, B, const N: usize> TryFromIterator<(K, V)> for ArrayMap<K, V, N, B>
1059+
impl<K, V, R, B> TryFromIterator<(K, V)> for ArrayMapFacade<K, V, R, B>
10311060
where
10321061
K: Eq + Hash,
1062+
R: RawTable<(K, V)> + Default,
10331063
B: BuildHasher + Default,
10341064
{
10351065
type Error = CapacityError;
10361066

10371067
fn try_from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Result<Self, Self::Error> {
1038-
let mut result = ArrayMap::with_build_hasher(B::default());
1068+
let mut result = Self::with_build_hasher(B::default());
10391069

10401070
for (key, value) in iter {
10411071
result.insert(key, value)?;
@@ -1045,9 +1075,10 @@ where
10451075
}
10461076
}
10471077

1048-
impl<K, V, B, const N: usize> TryExtend<(K, V)> for ArrayMap<K, V, N, B>
1078+
impl<K, V, R, B> TryExtend<(K, V)> for ArrayMapFacade<K, V, R, B>
10491079
where
10501080
K: Eq + Hash,
1081+
R: RawTable<(K, V)>,
10511082
B: BuildHasher,
10521083
{
10531084
type Error = CapacityError;
@@ -1061,10 +1092,11 @@ where
10611092
}
10621093
}
10631094

1064-
impl<'a, K, V, B, const N: usize> TryExtend<(&'a K, &'a V)> for ArrayMap<K, V, N, B>
1095+
impl<'a, K, V, R, B> TryExtend<(&'a K, &'a V)> for ArrayMapFacade<K, V, R, B>
10651096
where
10661097
K: Eq + Hash + Copy,
10671098
V: Copy,
1099+
R: RawTable<(K, V)>,
10681100
B: BuildHasher,
10691101
{
10701102
type Error = CapacityError;

0 commit comments

Comments
 (0)