Skip to main content

mule_map/mule_map/
iterators.rs

1use crate::MuleMap;
2use crate::mule_map::Key;
3use std::collections::HashMap;
4use std::fmt::Debug;
5use std::hash::BuildHasher;
6use std::iter::Enumerate;
7use std::iter::FilterMap;
8
9#[must_use]
10#[inline]
11fn key_from_index<K, const TABLE_MIN_VALUE: i128>(index: usize) -> K
12where
13    K: Key<TABLE_MIN_VALUE>,
14{
15    K::add_promoted(
16        K::i128_as_promoted(TABLE_MIN_VALUE),
17        K::usize_as_promoted(index),
18    )
19}
20
21// MuleMapIter
22
23type IterLeftSide<'a, K, V> =
24    std::iter::Map<std::collections::hash_map::Iter<'a, K, V>, fn((&'a K, &'a V)) -> (K, &'a V)>;
25
26type IterRightSide<'a, K, V> = FilterMap<
27    Enumerate<std::slice::Iter<'a, Option<V>>>,
28    fn((usize, &'a Option<V>)) -> Option<(K, &'a V)>,
29>;
30
31#[inline]
32#[must_use]
33fn map_fn<'a, K, V>((key, val): (&'a K, &'a V)) -> (K, &'a V)
34where
35    K: Copy,
36{
37    (*key, val)
38}
39
40#[inline]
41#[must_use]
42fn filter_map_fn<K, V, const TABLE_MIN_VALUE: i128>(
43    (index, value): (usize, &Option<V>),
44) -> Option<(K, &V)>
45where
46    K: Key<TABLE_MIN_VALUE>,
47{
48    Some(key_from_index::<K, TABLE_MIN_VALUE>(index)).zip(value.as_ref())
49}
50
51/// An iterator over the entries of a [`MuleMap`].
52#[derive(Debug, Clone)]
53pub struct Iter<'a, K, V, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize> {
54    iter: std::iter::Chain<IterLeftSide<'a, K, V>, IterRightSide<'a, K, V>>,
55}
56
57impl<'a, K, V, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize>
58    Iter<'a, K, V, TABLE_MIN_VALUE, TABLE_SIZE>
59where
60    K: Key<TABLE_MIN_VALUE>,
61{
62    #[inline]
63    #[must_use]
64    fn from_hash_map_and_table<S>(
65        hash_map: &'a HashMap<K, V, S>,
66        table: &'a [Option<V>; TABLE_SIZE],
67    ) -> Self
68    where
69        S: BuildHasher,
70    {
71        type MapFn<'a, K, V> = fn((&'a K, &'a V)) -> (K, &'a V);
72        type FilterMapFn<'a, K, V> = fn((usize, &Option<V>)) -> Option<(K, &V)>;
73
74        let left_iter: std::iter::Map<_, MapFn<'a, K, V>> = hash_map
75            .iter()
76            .map(map_fn as fn((&'a K, &'a V)) -> (K, &'a V));
77        let right_iter: FilterMap<_, FilterMapFn<'a, K, V>> = table.iter().enumerate().filter_map(
78            filter_map_fn::<K, V, TABLE_MIN_VALUE> as fn((usize, &Option<V>)) -> Option<(K, &V)>,
79        );
80
81        Iter {
82            iter: left_iter.chain(right_iter),
83        }
84    }
85}
86
87impl<'a, K, V, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize> Iterator
88    for Iter<'a, K, V, TABLE_MIN_VALUE, TABLE_SIZE>
89{
90    type Item = (K, &'a V);
91
92    #[inline]
93    fn next(&mut self) -> Option<Self::Item> {
94        self.iter.next()
95    }
96
97    #[inline]
98    fn size_hint(&self) -> (usize, Option<usize>) {
99        self.iter.size_hint()
100    }
101}
102
103impl<K, V, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize> std::iter::FusedIterator
104    for Iter<'_, K, V, TABLE_MIN_VALUE, TABLE_SIZE>
105{
106}
107
108// MuleMapIterMut
109
110type IterMutLeftSide<'a, K, V> = std::iter::Map<
111    std::collections::hash_map::IterMut<'a, K, V>,
112    fn((&'a K, &'a mut V)) -> (K, &'a mut V),
113>;
114
115type IterMutRightSide<'a, K, V> = FilterMap<
116    Enumerate<std::slice::IterMut<'a, Option<V>>>,
117    fn((usize, &'a mut Option<V>)) -> Option<(K, &'a mut V)>,
118>;
119
120#[inline]
121#[must_use]
122fn map_fn_mut<'a, K, V>((key, val): (&'a K, &'a mut V)) -> (K, &'a mut V)
123where
124    K: Copy,
125{
126    (*key, val)
127}
128
129#[inline]
130#[must_use]
131fn filter_map_fn_mut<K, V, const TABLE_MIN_VALUE: i128>(
132    (index, value): (usize, &mut Option<V>),
133) -> Option<(K, &mut V)>
134where
135    K: Key<TABLE_MIN_VALUE>,
136{
137    Some(key_from_index::<K, TABLE_MIN_VALUE>(index)).zip(value.as_mut())
138}
139
140/// A mutable iterator over the entries of a [`MuleMap`].
141#[derive(Debug)]
142pub struct IterMut<'a, K, V, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize> {
143    iter: std::iter::Chain<IterMutLeftSide<'a, K, V>, IterMutRightSide<'a, K, V>>,
144}
145
146impl<'a, K, V, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize>
147    IterMut<'a, K, V, TABLE_MIN_VALUE, TABLE_SIZE>
148where
149    K: Key<TABLE_MIN_VALUE>,
150{
151    #[inline]
152    #[must_use]
153    fn from_hash_map_and_table<S>(
154        hash_map: &'a mut HashMap<K, V, S>,
155        table: &'a mut [Option<V>; TABLE_SIZE],
156    ) -> Self
157    where
158        S: BuildHasher,
159    {
160        type MapFn<'a, K, V> = fn((&'a K, &'a mut V)) -> (K, &'a mut V);
161        type FilterMapFn<'a, K, V> = fn((usize, &mut Option<V>)) -> Option<(K, &mut V)>;
162
163        let left_iter: std::iter::Map<_, MapFn<'a, K, V>> = hash_map
164            .iter_mut()
165            .map(map_fn_mut as fn((&'a K, &'a mut V)) -> (K, &'a mut V));
166        let right_iter: FilterMap<_, FilterMapFn<'a, K, V>> =
167            table.iter_mut().enumerate().filter_map(
168                filter_map_fn_mut::<K, V, TABLE_MIN_VALUE>
169                    as fn((usize, &mut Option<V>)) -> Option<(K, &mut V)>,
170            );
171
172        IterMut {
173            iter: left_iter.chain(right_iter),
174        }
175    }
176}
177
178impl<'a, K, V, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize> Iterator
179    for IterMut<'a, K, V, TABLE_MIN_VALUE, TABLE_SIZE>
180{
181    type Item = (K, &'a mut V);
182
183    #[inline]
184    fn next(&mut self) -> Option<Self::Item> {
185        self.iter.next()
186    }
187
188    #[inline]
189    fn size_hint(&self) -> (usize, Option<usize>) {
190        self.iter.size_hint()
191    }
192}
193
194impl<K, V, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize> std::iter::FusedIterator
195    for IterMut<'_, K, V, TABLE_MIN_VALUE, TABLE_SIZE>
196{
197}
198
199// MuleMapIntoIter
200
201type IntoIterRightSide<K, V, const TABLE_SIZE: usize> = FilterMap<
202    Enumerate<std::array::IntoIter<Option<V>, TABLE_SIZE>>,
203    fn((usize, Option<V>)) -> Option<(K, V)>,
204>;
205
206#[inline]
207#[must_use]
208fn filter_map_fn_into<K, V, const TABLE_MIN_VALUE: i128>(
209    (index, value): (usize, Option<V>),
210) -> Option<(K, V)>
211where
212    K: Key<TABLE_MIN_VALUE>,
213{
214    Some(key_from_index::<K, TABLE_MIN_VALUE>(index)).zip(value)
215}
216
217/// An owning iterator over the entries of a [`MuleMap`].
218#[derive(Debug)]
219pub struct IntoIter<K, V, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize> {
220    iter: std::iter::Chain<
221        std::collections::hash_map::IntoIter<K, V>,
222        IntoIterRightSide<K, V, TABLE_SIZE>,
223    >,
224}
225
226impl<K, V, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize>
227    IntoIter<K, V, TABLE_MIN_VALUE, TABLE_SIZE>
228where
229    K: Key<TABLE_MIN_VALUE>,
230{
231    #[inline]
232    fn from_hash_map_and_table<S>(
233        hash_map: HashMap<K, V, S>,
234        table: [Option<V>; TABLE_SIZE],
235    ) -> Self
236    where
237        S: BuildHasher,
238    {
239        type FilterMapFn<K, V> = fn((usize, Option<V>)) -> Option<(K, V)>;
240
241        let left_iter: std::collections::hash_map::IntoIter<K, V> = hash_map.into_iter();
242        let right_iter: FilterMap<_, FilterMapFn<K, V>> = table.into_iter().enumerate().filter_map(
243            filter_map_fn_into::<K, V, TABLE_MIN_VALUE> as fn((usize, Option<V>)) -> Option<(K, V)>,
244        );
245
246        IntoIter {
247            iter: left_iter.chain(right_iter),
248        }
249    }
250}
251
252impl<K, V, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize> Iterator
253    for IntoIter<K, V, TABLE_MIN_VALUE, TABLE_SIZE>
254{
255    type Item = (K, V);
256
257    #[inline]
258    fn next(&mut self) -> Option<Self::Item> {
259        self.iter.next()
260    }
261
262    #[inline]
263    fn size_hint(&self) -> (usize, Option<usize>) {
264        self.iter.size_hint()
265    }
266}
267
268impl<K, V, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize> std::iter::FusedIterator
269    for IntoIter<K, V, TABLE_MIN_VALUE, TABLE_SIZE>
270{
271}
272
273// Drain
274
275type DrainIterRightSide<'a, K, V, const TABLE_SIZE: usize> = FilterMap<
276    Enumerate<std::slice::IterMut<'a, Option<V>>>,
277    fn((usize, &mut Option<V>)) -> Option<(K, V)>,
278>;
279
280#[inline]
281#[must_use]
282fn filter_map_fn_drain<K, V, const TABLE_MIN_VALUE: i128>(
283    (index, value): (usize, &mut Option<V>),
284) -> Option<(K, V)>
285where
286    K: Key<TABLE_MIN_VALUE>,
287{
288    Some(key_from_index::<K, TABLE_MIN_VALUE>(index)).zip(value.take())
289}
290
291/// An draining iterator over the entries of a [`MuleMap`].
292#[derive(Debug)]
293pub struct DrainIter<'a, K, V, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize> {
294    iter: std::iter::Chain<
295        std::collections::hash_map::Drain<'a, K, V>,
296        DrainIterRightSide<'a, K, V, TABLE_SIZE>,
297    >,
298}
299
300impl<'a, K, V, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize>
301    DrainIter<'a, K, V, TABLE_MIN_VALUE, TABLE_SIZE>
302where
303    K: Key<TABLE_MIN_VALUE>,
304{
305    #[inline]
306    #[must_use]
307    fn from_hash_map_and_table<S>(
308        hash_map: &'a mut HashMap<K, V, S>,
309        table: &'a mut [Option<V>; TABLE_SIZE],
310    ) -> Self
311    where
312        S: BuildHasher,
313    {
314        type FilterMapFn<K, V> = fn((usize, &mut Option<V>)) -> Option<(K, V)>;
315
316        let left_iter = hash_map.drain();
317
318        let right_iter: FilterMap<_, FilterMapFn<K, V>> = table.iter_mut().enumerate().filter_map(
319            filter_map_fn_drain::<K, V, TABLE_MIN_VALUE>
320                as fn((usize, &mut Option<V>)) -> Option<(K, V)>,
321        );
322        Self {
323            // Note: Can't hold a `&mut` to both table and iter in `MuleMapDrainIter`, but we need to be sure to consume
324            // all of the elements so that the original `MuleMap` is empty after dropped. We could have used an owned
325            // table, but that would have made an extra copy. This could be made more efficient using unsafe.
326            iter: left_iter.chain(right_iter),
327        }
328    }
329}
330
331impl<K, V, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize> Drop
332    for DrainIter<'_, K, V, TABLE_MIN_VALUE, TABLE_SIZE>
333{
334    #[inline]
335    fn drop(&mut self) {
336        for _ in &mut self.iter {}
337    }
338}
339
340impl<K, V, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize> Iterator
341    for DrainIter<'_, K, V, TABLE_MIN_VALUE, TABLE_SIZE>
342{
343    type Item = (K, V);
344
345    #[inline]
346    fn next(&mut self) -> Option<Self::Item> {
347        self.iter.next()
348    }
349
350    #[inline]
351    fn size_hint(&self) -> (usize, Option<usize>) {
352        self.iter.size_hint()
353    }
354}
355
356impl<K, V, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize> std::iter::FusedIterator
357    for DrainIter<'_, K, V, TABLE_MIN_VALUE, TABLE_SIZE>
358{
359}
360
361// Keys
362
363type KeysLeftSide<'a, K, V> =
364    std::iter::Map<std::collections::hash_map::Keys<'a, K, V>, fn(&'a K) -> K>;
365
366type KeysRightSide<'a, K, V> =
367    FilterMap<Enumerate<std::slice::Iter<'a, Option<V>>>, fn((usize, &'a Option<V>)) -> Option<K>>;
368
369#[inline]
370#[must_use]
371fn map_fn_keys<K>(key: &K) -> K
372where
373    K: Copy,
374{
375    *key
376}
377
378#[inline]
379#[must_use]
380fn filter_map_fn_keys<K, V, const TABLE_MIN_VALUE: i128>(
381    (index, value): (usize, &Option<V>),
382) -> Option<K>
383where
384    K: Key<TABLE_MIN_VALUE>,
385{
386    value
387        .as_ref()
388        .map(|_| key_from_index::<K, TABLE_MIN_VALUE>(index))
389}
390
391/// An iterator over the keys of a [`MuleMap`].
392#[derive(Debug, Clone)]
393pub struct Keys<'a, K, V, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize> {
394    iter: std::iter::Chain<KeysLeftSide<'a, K, V>, KeysRightSide<'a, K, V>>,
395}
396
397impl<'a, K, V, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize>
398    Keys<'a, K, V, TABLE_MIN_VALUE, TABLE_SIZE>
399where
400    K: Key<TABLE_MIN_VALUE>,
401{
402    #[inline]
403    #[must_use]
404    fn from_hash_map_and_table<S>(
405        hash_map: &'a HashMap<K, V, S>,
406        table: &'a [Option<V>; TABLE_SIZE],
407    ) -> Self
408    where
409        S: BuildHasher,
410    {
411        type MapFn<'a, K> = fn(&'a K) -> K;
412        type FilterMapFn<'a, K, V> = fn((usize, &Option<V>)) -> Option<K>;
413
414        let left_iter: std::iter::Map<_, MapFn<'a, K>> =
415            hash_map.keys().map(map_fn_keys as fn(&'a K) -> K);
416        let right_iter: FilterMap<_, FilterMapFn<'a, K, V>> = table.iter().enumerate().filter_map(
417            filter_map_fn_keys::<K, V, TABLE_MIN_VALUE> as fn((usize, &Option<V>)) -> Option<K>,
418        );
419
420        Keys {
421            iter: left_iter.chain(right_iter),
422        }
423    }
424}
425
426impl<K, V, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize> Iterator
427    for Keys<'_, K, V, TABLE_MIN_VALUE, TABLE_SIZE>
428{
429    type Item = K;
430
431    #[inline]
432    fn next(&mut self) -> Option<Self::Item> {
433        self.iter.next()
434    }
435
436    #[inline]
437    fn size_hint(&self) -> (usize, Option<usize>) {
438        self.iter.size_hint()
439    }
440}
441
442impl<K, V, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize> std::iter::FusedIterator
443    for Keys<'_, K, V, TABLE_MIN_VALUE, TABLE_SIZE>
444{
445}
446
447// IntoKeys
448
449/// An owning iterator over the keys of a [`MuleMap`].
450#[derive(Debug)]
451pub struct IntoKeys<K, V, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize> {
452    iter: std::iter::Chain<std::collections::hash_map::IntoKeys<K, V>, std::vec::IntoIter<K>>,
453}
454
455impl<K, V, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize>
456    IntoKeys<K, V, TABLE_MIN_VALUE, TABLE_SIZE>
457where
458    K: Key<TABLE_MIN_VALUE>,
459{
460    #[inline]
461    #[must_use]
462    fn from_hash_map_and_table<S>(
463        hash_map: HashMap<K, V, S>,
464        table: &[Option<V>; TABLE_SIZE],
465    ) -> Self
466    where
467        S: BuildHasher,
468    {
469        let left_iter = hash_map.into_keys();
470
471        let table_keys: Vec<K> = table
472            .iter()
473            .enumerate()
474            .filter_map(
475                filter_map_fn_keys::<K, V, TABLE_MIN_VALUE> as fn((usize, &Option<V>)) -> Option<K>,
476            )
477            .collect();
478
479        IntoKeys {
480            iter: left_iter.chain(table_keys),
481        }
482    }
483}
484
485impl<K, V, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize> Iterator
486    for IntoKeys<K, V, TABLE_MIN_VALUE, TABLE_SIZE>
487{
488    type Item = K;
489
490    #[inline]
491    fn next(&mut self) -> Option<Self::Item> {
492        self.iter.next()
493    }
494
495    #[inline]
496    fn size_hint(&self) -> (usize, Option<usize>) {
497        self.iter.size_hint()
498    }
499}
500
501impl<K, V, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize> std::iter::FusedIterator
502    for IntoKeys<K, V, TABLE_MIN_VALUE, TABLE_SIZE>
503{
504}
505
506// Values
507
508type ValuesRightSide<'a, V> =
509    FilterMap<std::slice::Iter<'a, Option<V>>, fn(&Option<V>) -> Option<&V>>;
510
511#[inline]
512#[must_use]
513#[allow(clippy::ref_option)]
514fn filter_map_fn_values<V, const TABLE_MIN_VALUE: i128>(value: &Option<V>) -> Option<&V> {
515    value.as_ref()
516}
517
518/// An iterator over the values of a [`MuleMap`].
519#[derive(Debug, Clone)]
520pub struct Values<'a, K, V, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize> {
521    iter: std::iter::Chain<std::collections::hash_map::Values<'a, K, V>, ValuesRightSide<'a, V>>,
522}
523
524impl<'a, K, V, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize>
525    Values<'a, K, V, TABLE_MIN_VALUE, TABLE_SIZE>
526{
527    #[inline]
528    #[must_use]
529    fn from_hash_map_and_table<S>(
530        hash_map: &'a HashMap<K, V, S>,
531        table: &'a [Option<V>; TABLE_SIZE],
532    ) -> Self
533    where
534        S: BuildHasher,
535    {
536        let left_iter = hash_map.values();
537        let right_iter = table
538            .iter()
539            .filter_map(filter_map_fn_values::<V, TABLE_MIN_VALUE> as fn(&Option<V>) -> Option<&V>);
540
541        Values {
542            iter: left_iter.chain(right_iter),
543        }
544    }
545}
546
547impl<'a, K, V, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize> Iterator
548    for Values<'a, K, V, TABLE_MIN_VALUE, TABLE_SIZE>
549{
550    type Item = &'a V;
551
552    #[inline]
553    fn next(&mut self) -> Option<Self::Item> {
554        self.iter.next()
555    }
556
557    #[inline]
558    fn size_hint(&self) -> (usize, Option<usize>) {
559        self.iter.size_hint()
560    }
561}
562
563impl<K, V, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize> std::iter::FusedIterator
564    for Values<'_, K, V, TABLE_MIN_VALUE, TABLE_SIZE>
565{
566}
567
568// ValuesMut
569
570type ValuesMutRightSide<'a, V> =
571    FilterMap<std::slice::IterMut<'a, Option<V>>, fn(&mut Option<V>) -> Option<&mut V>>;
572
573#[inline]
574#[must_use]
575fn filter_map_fn_values_mut<V, const TABLE_MIN_VALUE: i128>(
576    value: &mut Option<V>,
577) -> Option<&mut V>
578where
579{
580    value.as_mut()
581}
582
583/// A mutable iterator over the values of a [`MuleMap`].
584#[derive(Debug)]
585pub struct ValuesMut<'a, K, V, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize> {
586    iter: std::iter::Chain<
587        std::collections::hash_map::ValuesMut<'a, K, V>,
588        ValuesMutRightSide<'a, V>,
589    >,
590}
591
592impl<'a, K, V, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize>
593    ValuesMut<'a, K, V, TABLE_MIN_VALUE, TABLE_SIZE>
594{
595    #[inline]
596    #[must_use]
597    fn from_hash_map_and_table<S>(
598        hash_map: &'a mut HashMap<K, V, S>,
599        table: &'a mut [Option<V>; TABLE_SIZE],
600    ) -> Self
601    where
602        S: BuildHasher,
603    {
604        let left_iter = hash_map.values_mut();
605        let right_iter = table.iter_mut().filter_map(
606            filter_map_fn_values_mut::<V, TABLE_MIN_VALUE> as fn(&mut Option<V>) -> Option<&mut V>,
607        );
608
609        ValuesMut {
610            iter: left_iter.chain(right_iter),
611        }
612    }
613}
614
615impl<'a, K, V, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize> Iterator
616    for ValuesMut<'a, K, V, TABLE_MIN_VALUE, TABLE_SIZE>
617{
618    type Item = &'a mut V;
619
620    #[inline]
621    fn next(&mut self) -> Option<Self::Item> {
622        self.iter.next()
623    }
624
625    #[inline]
626    fn size_hint(&self) -> (usize, Option<usize>) {
627        self.iter.size_hint()
628    }
629}
630
631impl<K, V, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize> std::iter::FusedIterator
632    for ValuesMut<'_, K, V, TABLE_MIN_VALUE, TABLE_SIZE>
633{
634}
635
636// IntoValues
637
638type IntoValuesRightSide<V, const TABLE_SIZE: usize> =
639    FilterMap<std::array::IntoIter<Option<V>, TABLE_SIZE>, fn(Option<V>) -> Option<V>>;
640
641#[inline]
642#[must_use]
643fn filter_map_fn_into_values<V, const TABLE_MIN_VALUE: i128>(value: Option<V>) -> Option<V>
644where
645{
646    value
647}
648
649/// An owning iterator over the values of a [`MuleMap`].
650#[derive(Debug)]
651pub struct IntoValues<K, V, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize> {
652    iter: std::iter::Chain<
653        std::collections::hash_map::IntoValues<K, V>,
654        IntoValuesRightSide<V, TABLE_SIZE>,
655    >,
656}
657
658impl<K, V, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize>
659    IntoValues<K, V, TABLE_MIN_VALUE, TABLE_SIZE>
660{
661    #[inline]
662    #[must_use]
663    fn from_hash_map_and_table<S>(
664        hash_map: HashMap<K, V, S>,
665        table: [Option<V>; TABLE_SIZE],
666    ) -> Self
667    where
668        S: BuildHasher,
669    {
670        let left_iter = hash_map.into_values();
671        let right_iter = table.into_iter().filter_map(
672            filter_map_fn_into_values::<V, TABLE_MIN_VALUE> as fn(Option<V>) -> Option<V>,
673        );
674
675        IntoValues {
676            iter: left_iter.chain(right_iter),
677        }
678    }
679}
680
681impl<K, V, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize> Iterator
682    for IntoValues<K, V, TABLE_MIN_VALUE, TABLE_SIZE>
683{
684    type Item = V;
685
686    #[inline]
687    fn next(&mut self) -> Option<Self::Item> {
688        self.iter.next()
689    }
690
691    #[inline]
692    fn size_hint(&self) -> (usize, Option<usize>) {
693        self.iter.size_hint()
694    }
695}
696
697impl<K, V, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize> std::iter::FusedIterator
698    for IntoValues<K, V, TABLE_MIN_VALUE, TABLE_SIZE>
699{
700}
701
702// MuleMap
703
704impl<K, V, S, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize>
705    MuleMap<K, V, S, TABLE_MIN_VALUE, TABLE_SIZE>
706where
707    K: Key<TABLE_MIN_VALUE>,
708    S: BuildHasher,
709{
710    /// An iterator visiting all key-value pairs in arbitrary order. The iterator element type is `(K, &'a V)`.
711    ///
712    /// # Example
713    ///
714    /// ```
715    /// use mule_map::MuleMap;
716    ///
717    /// let mut mule_map = MuleMap::<u32, i32, fnv_rs::FnvBuildHasher>::default();
718    /// mule_map.bump_int(10);
719    /// mule_map.bump_int(10);
720    /// mule_map.bump_int(999_999);
721    ///
722    /// let mut count = 0;
723    /// for (key, value) in mule_map.iter()
724    /// {
725    ///     assert!((key == 10 && *value == 2) || (key == 999_999 && *value == 1));
726    ///     count += 1;
727    /// }
728    /// assert_eq!(count, 2);
729    /// ```
730    ///
731    /// # Performance
732    /// O(capacity of the [`HashMap`]) + O(`TABLE_SIZE` of the lookup table). Currently all `TABLE_SIZE` elements of the
733    /// lookup table will be visited.
734    ///
735    /// Analogous to [`HashMap::iter`]
736    #[inline]
737    #[must_use]
738    pub fn iter(&self) -> Iter<'_, K, V, TABLE_MIN_VALUE, TABLE_SIZE> {
739        Iter::<K, V, TABLE_MIN_VALUE, TABLE_SIZE>::from_hash_map_and_table(
740            &self.hash_map,
741            &self.table,
742        )
743    }
744
745    /// A mutable iterator visiting all key-value pairs in arbitrary order. The iterator element type is `(K, &'a mut V)`.
746    ///
747    /// # Example
748    ///
749    /// ```
750    /// use mule_map::MuleMap;
751    ///
752    /// let mut mule_map = MuleMap::<u32, i32, fnv_rs::FnvBuildHasher>::default();
753    /// mule_map.bump_int(10);
754    /// mule_map.bump_int(10);
755    /// mule_map.bump_int(999_999);
756    ///
757    /// let mut count = 0;
758    /// for (key, value) in mule_map.iter_mut()
759    /// {
760    ///     *value *= 2;
761    ///     assert!((key == 10 && *value == 4) || (key == 999_999 && *value == 2));
762    ///     count += 1;
763    /// }
764    /// assert_eq!(count, 2);
765    /// ```
766    ///
767    /// # Performance
768    /// O(capacity of the [`HashMap`]) + O(`TABLE_SIZE` of the lookup table). Currently all `TABLE_SIZE` elements of the
769    /// lookup table will be visited.
770    ///
771    /// Analogous to [`HashMap::iter_mut`]
772    #[inline]
773    #[must_use]
774    pub fn iter_mut(&mut self) -> IterMut<'_, K, V, TABLE_MIN_VALUE, TABLE_SIZE> {
775        IterMut::<K, V, TABLE_MIN_VALUE, TABLE_SIZE>::from_hash_map_and_table(
776            &mut self.hash_map,
777            &mut self.table,
778        )
779    }
780
781    /// Clears the map, returning all key-value pairs as an iterator. Keeps the allocated memory for reuse. If the
782    /// returned iterator is dropped before being fully consumed, it drops the remaining key-value pairs. The returned
783    /// iterator keeps a mutable borrow on the map to optimize its implementation.
784    ///
785    /// # Example
786    ///
787    /// ```
788    /// use mule_map::MuleMap;
789    ///
790    /// let mut mule_map = MuleMap::<u32, i32, fnv_rs::FnvBuildHasher>::default();
791    /// mule_map.bump_int(10);
792    /// mule_map.bump_int(10);
793    /// mule_map.bump_int(999_999);
794    ///
795    /// for (key, value)  in mule_map.drain().take(1) {
796    ///     assert!((key == 10 && value == 2) || (key == 999_999 && value == 1));
797    /// }
798    /// assert!(mule_map.is_empty());
799    /// ```
800    ///
801    /// # Performance
802    /// O(capacity of the [`HashMap`]) + O(`TABLE_SIZE` of the lookup table). Currently all `TABLE_SIZE` elements of the
803    /// lookup table will be visited.
804    ///
805    /// Analogous to [`HashMap::drain`]
806    #[inline]
807    #[must_use]
808    pub fn drain(&mut self) -> DrainIter<'_, K, V, TABLE_MIN_VALUE, TABLE_SIZE> {
809        DrainIter::<K, V, TABLE_MIN_VALUE, TABLE_SIZE>::from_hash_map_and_table(
810            &mut self.hash_map,
811            &mut self.table,
812        )
813    }
814
815    /// An iterator visiting all keys in arbitrary order. The iterator element type is `K`.
816    ///
817    /// # Example
818    ///
819    /// ```
820    /// use mule_map::MuleMap;
821    ///
822    /// let mut mule_map = MuleMap::<u32, i32, fnv_rs::FnvBuildHasher>::default();
823    /// mule_map.bump_int(10);
824    /// mule_map.bump_int(10);
825    /// mule_map.bump_int(999_999);
826    ///
827    /// let mut count = 0;
828    /// for key in mule_map.keys()
829    /// {
830    ///     assert!(key == 10 || key == 999_999);
831    ///     count += 1;
832    /// }
833    /// assert_eq!(count, 2);
834    /// ```
835    ///
836    /// # Performance
837    /// O(capacity of the [`HashMap`]) + O(`TABLE_SIZE` of the lookup table). Currently all `TABLE_SIZE` elements of the
838    /// lookup table will be visited.
839    ///
840    /// Analogous to [`HashMap::keys`]
841    #[inline]
842    #[must_use]
843    pub fn keys(&self) -> Keys<'_, K, V, TABLE_MIN_VALUE, TABLE_SIZE> {
844        Keys::<'_, K, V, TABLE_MIN_VALUE, TABLE_SIZE>::from_hash_map_and_table(
845            &self.hash_map,
846            &self.table,
847        )
848    }
849
850    /// Creates a consuming iterator visiting all the keys in arbitrary order. The map cannot be used after calling
851    /// this. The iterator element type is `K`.
852    ///
853    /// # Example
854    ///
855    /// ```
856    /// use mule_map::MuleMap;
857    ///
858    /// let mut mule_map = MuleMap::<u32, i32, fnv_rs::FnvBuildHasher>::default();
859    /// mule_map.bump_int(10);
860    /// mule_map.bump_int(10);
861    /// mule_map.bump_int(999_999);
862    ///
863    /// let mut count = 0;
864    /// for key in mule_map.into_keys()
865    /// {
866    ///     assert!(key == 10 || key == 999_999);
867    ///     count += 1;
868    /// }
869    /// assert_eq!(count, 2);
870    /// ```
871    ///
872    /// # Performance
873    /// O(capacity of the [`HashMap`]) + O(`TABLE_SIZE` of the lookup table). Currently all `TABLE_SIZE` elements of the
874    /// lookup table will be visited.
875    ///
876    /// Analogous to [`HashMap::into_keys`]
877    #[inline]
878    #[must_use]
879    pub fn into_keys(self) -> IntoKeys<K, V, TABLE_MIN_VALUE, TABLE_SIZE> {
880        IntoKeys::<K, V, TABLE_MIN_VALUE, TABLE_SIZE>::from_hash_map_and_table(
881            self.hash_map,
882            &self.table,
883        )
884    }
885
886    /// Creates an iterator visiting all the values in arbitrary order. The iterator element type is `&'a V`.
887    ///
888    /// # Example
889    ///
890    /// ```
891    /// use mule_map::MuleMap;
892    ///
893    /// let mut mule_map = MuleMap::<u32, i32, fnv_rs::FnvBuildHasher>::default();
894    /// mule_map.bump_int(10);
895    /// mule_map.bump_int(10);
896    /// mule_map.bump_int(999_999);
897    ///
898    /// let mut count = 0;
899    /// for val in mule_map.values()
900    /// {
901    ///     assert!(*val == 1 || *val == 2);
902    ///     count += 1;
903    /// }
904    /// assert_eq!(count, 2);
905    /// ```
906    ///
907    /// # Performance
908    /// O(capacity of the [`HashMap`]) + O(`TABLE_SIZE` of the lookup table). Currently all `TABLE_SIZE` elements of the
909    /// lookup table will be visited.
910    ///
911    /// Analogous to [`HashMap::values`]
912    #[inline]
913    #[must_use]
914    pub fn values(&self) -> Values<'_, K, V, TABLE_MIN_VALUE, TABLE_SIZE> {
915        Values::<'_, K, V, TABLE_MIN_VALUE, TABLE_SIZE>::from_hash_map_and_table(
916            &self.hash_map,
917            &self.table,
918        )
919    }
920
921    /// Creates an iterator visiting all the values in arbitrary order. The iterator element type is `&'a mut V`.
922    ///
923    /// # Example
924    ///
925    /// ```
926    /// use mule_map::MuleMap;
927    ///
928    /// let mut mule_map = MuleMap::<u32, i32, fnv_rs::FnvBuildHasher>::default();
929    /// mule_map.bump_int(10);
930    /// mule_map.bump_int(10);
931    /// mule_map.bump_int(999_999);
932    ///
933    /// let mut count = 0;
934    /// for val in mule_map.values_mut()
935    /// {
936    ///     *val *= 2;
937    ///     assert!(*val == 2 || *val == 4);
938    ///     count += 1;
939    /// }
940    /// assert_eq!(count, 2);
941    /// ```
942    ///
943    /// # Performance
944    /// O(capacity of the [`HashMap`]) + O(`TABLE_SIZE` of the lookup table). Currently all `TABLE_SIZE` elements of the
945    /// lookup table will be visited.
946    ///
947    ///  Analogous to [`HashMap::values_mut`]
948    #[inline]
949    #[must_use]
950    pub fn values_mut(&mut self) -> ValuesMut<'_, K, V, TABLE_MIN_VALUE, TABLE_SIZE> {
951        ValuesMut::<'_, K, V, TABLE_MIN_VALUE, TABLE_SIZE>::from_hash_map_and_table(
952            &mut self.hash_map,
953            &mut self.table,
954        )
955    }
956
957    /// Creates an iterator consuming all the values in arbitrary order. The map cannot be used after calling this. The
958    /// iterator element type is `V`.
959    ///
960    /// # Example
961    ///
962    /// ```
963    /// use mule_map::MuleMap;
964    ///
965    /// let mut mule_map = MuleMap::<u32, i32, fnv_rs::FnvBuildHasher>::default();
966    /// mule_map.bump_int(10);
967    /// mule_map.bump_int(10);
968    /// mule_map.bump_int(999_999);
969    ///
970    /// let mut count = 0;
971    /// for val in mule_map.into_values()
972    /// {
973    ///     assert!(val == 1 || val == 2);
974    ///     count += 1;
975    /// }
976    /// assert_eq!(count, 2);
977    /// ```
978    ///
979    /// # Performance
980    /// O(capacity of the [`HashMap`]) + O(`TABLE_SIZE` of the lookup table). Currently all `TABLE_SIZE` elements of the
981    /// lookup table will be visited.
982    ///
983    ///  Analogous to [`HashMap::into_values`]
984    #[inline]
985    #[must_use]
986    pub fn into_values(self) -> IntoValues<K, V, TABLE_MIN_VALUE, TABLE_SIZE> {
987        IntoValues::<K, V, TABLE_MIN_VALUE, TABLE_SIZE>::from_hash_map_and_table(
988            self.hash_map,
989            self.table,
990        )
991    }
992
993    /// Retains only the elements specified by the predicate.
994    ///
995    /// In other words, remove all pairs (k, v) for which f(&k, &mut v) returns false. The elements are visited in
996    /// unsorted (and unspecified) order.
997    ///
998    /// # Example
999    ///
1000    /// ```
1001    /// use mule_map::MuleMap;
1002    ///
1003    /// let mut mule_map = MuleMap::<u32, i32, fnv_rs::FnvBuildHasher>::default();
1004    /// mule_map.bump_int(10);
1005    /// mule_map.bump_int(10);
1006    /// mule_map.bump_int(999_999);
1007    ///
1008    /// mule_map.retain(|&k, _| k % 2 == 0);
1009    /// assert_eq!(mule_map.len(), 1);
1010    /// assert_eq!(mule_map.get(10), Some(&2));
1011    /// ```
1012    ///
1013    /// # Performance
1014    /// O(capacity of the [`HashMap`]) + O(`TABLE_SIZE` of the lookup table). Currently all `TABLE_SIZE` elements of the
1015    /// lookup table will be visited.
1016    ///
1017    ///  Analogous to [`HashMap::retain`]
1018    #[inline]
1019    pub fn retain<F>(&mut self, mut f: F)
1020    where
1021        F: FnMut(&K, &mut V) -> bool,
1022    {
1023        for (index, value) in self.table.iter_mut().enumerate() {
1024            if let Some(x) = value
1025                && !f(&key_from_index::<K, TABLE_MIN_VALUE>(index), x)
1026            {
1027                *value = None;
1028            }
1029        }
1030
1031        self.hash_map.retain(f);
1032    }
1033}
1034
1035// IntoIterator
1036impl<'a, K, V, S, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize> IntoIterator
1037    for &'a MuleMap<K, V, S, TABLE_MIN_VALUE, TABLE_SIZE>
1038where
1039    K: Key<TABLE_MIN_VALUE>,
1040    S: BuildHasher,
1041{
1042    type Item = (K, &'a V);
1043    type IntoIter = Iter<'a, K, V, TABLE_MIN_VALUE, TABLE_SIZE>;
1044
1045    #[inline]
1046    fn into_iter(self) -> Iter<'a, K, V, TABLE_MIN_VALUE, TABLE_SIZE> {
1047        self.iter()
1048    }
1049}
1050
1051impl<'a, K, V, S, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize> IntoIterator
1052    for &'a mut MuleMap<K, V, S, TABLE_MIN_VALUE, TABLE_SIZE>
1053where
1054    K: Key<TABLE_MIN_VALUE>,
1055    S: BuildHasher,
1056{
1057    type Item = (K, &'a mut V);
1058    type IntoIter = IterMut<'a, K, V, TABLE_MIN_VALUE, TABLE_SIZE>;
1059
1060    #[inline]
1061    fn into_iter(self) -> IterMut<'a, K, V, TABLE_MIN_VALUE, TABLE_SIZE> {
1062        self.iter_mut()
1063    }
1064}
1065
1066impl<K, V, S, const TABLE_MIN_VALUE: i128, const TABLE_SIZE: usize> IntoIterator
1067    for MuleMap<K, V, S, TABLE_MIN_VALUE, TABLE_SIZE>
1068where
1069    K: Key<TABLE_MIN_VALUE>,
1070    S: BuildHasher,
1071{
1072    type Item = (K, V);
1073    type IntoIter = IntoIter<K, V, TABLE_MIN_VALUE, TABLE_SIZE>;
1074
1075    #[inline]
1076    fn into_iter(self) -> IntoIter<K, V, TABLE_MIN_VALUE, TABLE_SIZE> {
1077        IntoIter::<K, V, TABLE_MIN_VALUE, TABLE_SIZE>::from_hash_map_and_table(
1078            self.hash_map,
1079            self.table,
1080        )
1081    }
1082}
1083
1084#[cfg(test)]
1085mod tests {
1086    use super::*;
1087
1088    #[test]
1089    fn test_key_from_index() {
1090        macro_rules! check_key_from_index_small {
1091            (type=$prim_type:ty) => {
1092                assert_eq!(
1093                    key_from_index::<$prim_type, { <$prim_type>::MIN as i128 }>(0),
1094                    <$prim_type>::MIN
1095                );
1096
1097                assert_eq!(
1098                    key_from_index::<$prim_type, { <$prim_type>::MIN as i128 }>(
1099                        (1 << (<$prim_type>::BITS + 1)) - 1
1100                    ),
1101                    <$prim_type>::MAX
1102                );
1103
1104                assert_eq!(
1105                    key_from_index::<$prim_type, { <$prim_type>::MAX as i128 }>(0),
1106                    <$prim_type>::MAX
1107                );
1108
1109                assert_eq!(
1110                    key_from_index::<$prim_type, { <$prim_type>::MAX as i128 / 2 }>(0),
1111                    <$prim_type>::MAX / 2
1112                );
1113
1114                assert_eq!(
1115                    key_from_index::<$prim_type, { <$prim_type>::MAX as i128 / 2 }>(
1116                        (<$prim_type>::MAX / 2) as usize + 1
1117                    ),
1118                    <$prim_type>::MAX
1119                );
1120            };
1121        }
1122
1123        check_key_from_index_small!(type=u8);
1124        check_key_from_index_small!(type=u16);
1125        check_key_from_index_small!(type=i8);
1126        check_key_from_index_small!(type=i16);
1127
1128        macro_rules! check_key_from_index_large {
1129            (type=$prim_type:ty) => {
1130                assert_eq!(
1131                    key_from_index::<$prim_type, { <$prim_type>::MIN as i128 }>(0),
1132                    <$prim_type>::MIN
1133                );
1134
1135                assert_eq!(
1136                    key_from_index::<$prim_type, { <$prim_type>::MIN as i128 }>(i32::MAX as usize),
1137                    (<$prim_type>::MIN as i128 + i32::MAX as i128) as $prim_type
1138                );
1139
1140                {
1141                    const fn largest_table_min() -> i128 {
1142                        if (<$prim_type>::BITS == 128) {
1143                            return i128::MAX;
1144                        }
1145                        <$prim_type>::MAX as i128
1146                    }
1147
1148                    assert_eq!(
1149                        key_from_index::<$prim_type, { largest_table_min() }>(0),
1150                        largest_table_min() as $prim_type
1151                    );
1152
1153                    assert_eq!(
1154                        key_from_index::<$prim_type, { largest_table_min() - (i32::MAX as i128) }>(
1155                            0
1156                        ),
1157                        (largest_table_min() - (i32::MAX as i128)) as $prim_type
1158                    );
1159
1160                    assert_eq!(
1161                        key_from_index::<$prim_type, { largest_table_min() - (i32::MAX as i128) }>(
1162                            i32::MAX as usize
1163                        ),
1164                        largest_table_min() as $prim_type
1165                    );
1166                }
1167            };
1168        }
1169
1170        #[allow(clippy::cast_lossless)]
1171        #[allow(clippy::cast_possible_wrap)]
1172        #[allow(clippy::cast_possible_truncation)]
1173        #[allow(clippy::cast_sign_loss)]
1174        {
1175            check_key_from_index_large!(type=u32);
1176            check_key_from_index_large!(type=u64);
1177            check_key_from_index_large!(type=u128);
1178            check_key_from_index_large!(type=usize);
1179
1180            check_key_from_index_large!(type=i32);
1181            check_key_from_index_large!(type=i64);
1182            check_key_from_index_large!(type=i128);
1183            check_key_from_index_large!(type=isize);
1184        }
1185    }
1186}