Skip to main content

gen_map/
slot.rs

1use crate::config::KeyConfig;
2use crate::key_piece::KeyPiece;
3use crate::parity::{Even, Odd};
4use core::fmt;
5use core::mem::ManuallyDrop;
6use core::ptr;
7
8/// The generation of a [`Slot`] together with its value. The variant says
9/// whether the generation is odd or even, and so whether the value is the
10/// slot's `T` or its `U`.
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
12pub enum Parity<G: KeyPiece, T, U> {
13    /// The generation is odd and the value is a `T`.
14    Odd(Odd<G>, T),
15    /// The generation is even and the value is a `U`.
16    Even(Even<G>, U),
17}
18
19/// The value of a [`Slot`]. `odd` is live while the slot's generation is odd,
20/// and `even` is live while it is even.
21union Value<T, U> {
22    odd: ManuallyDrop<T>,
23    even: ManuallyDrop<U>,
24}
25
26/// A generation together with a `T` while the generation is odd, or a `U`
27/// while it is even.
28///
29/// A [`GenMap`](crate::GenMap) keeps each of its values in a slot like this,
30/// its [`MapSlot`](crate::MapSlot). A key's generation is odd, so a key that
31/// matches a slot finds its `T`.
32///
33/// # Examples
34///
35/// ```
36/// use gen_map::{Even, GenMap, Parity, Slot};
37///
38/// let mut map = GenMap::new();
39/// let key = map.insert("a");
40///
41/// // The slot starts out at generation zero, so it holds a `U`.
42/// let mut slot = Slot::<u32, u64, ()>::new(Parity::Even(Even::ZERO, ()));
43/// assert!(slot.get_odd(key.generation()).is_none());
44///
45/// slot.replace(Parity::Odd(key.generation(), 10));
46/// assert_eq!(slot.get_odd(key.generation()), Some(&10));
47/// ```
48pub struct Slot<G: KeyPiece, T, U> {
49    generation: G,
50    /// The parity of `generation` says which field is live.
51    value: Value<T, U>,
52}
53
54impl<G: KeyPiece, T, U> Slot<G, T, U> {
55    /// Creates a slot with the generation and the value in `parity`.
56    #[inline]
57    pub fn new(parity: Parity<G, T, U>) -> Self {
58        match parity {
59            Parity::Odd(generation, value) => Self::new_odd(generation, value),
60            Parity::Even(generation, value) => Self::new_even(generation, value),
61        }
62    }
63
64    /// Creates a slot with an odd `generation` and a `T`.
65    #[inline]
66    pub fn new_odd(generation: Odd<G>, value: T) -> Self {
67        Self {
68            generation: G::from_non_zero(generation.get()),
69            value: Value {
70                odd: ManuallyDrop::new(value),
71            },
72        }
73    }
74
75    /// Creates a slot with an even `generation` and a `U`.
76    #[inline]
77    pub fn new_even(generation: Even<G>, value: U) -> Self {
78        Self {
79            generation: generation.get(),
80            value: Value {
81                even: ManuallyDrop::new(value),
82            },
83        }
84    }
85
86    /// Returns the slot's generation.
87    #[inline]
88    pub fn generation(&self) -> G {
89        self.generation
90    }
91
92    /// Returns `true` if the generation is odd, which means the slot holds a
93    /// `T`.
94    #[inline]
95    pub fn is_odd(&self) -> bool {
96        self.generation.is_odd()
97    }
98
99    /// Returns `true` if the generation is even, which means the slot holds a
100    /// `U`.
101    #[inline]
102    pub fn is_even(&self) -> bool {
103        !self.generation.is_odd()
104    }
105
106    /// Returns the generation and a reference to the value.
107    #[inline]
108    pub fn as_parity(&self) -> Parity<G, &T, &U> {
109        // SAFETY: the parity of the generation says which field is live. The
110        // first branch only runs for an odd generation, so it reads `odd` and
111        // wraps the generation in `Odd`, and the second branch does the same
112        // with `even` and `Even` for an even generation.
113        unsafe {
114            if self.is_odd() {
115                Parity::Odd(Odd::new_unchecked(self.generation), &self.value.odd)
116            } else {
117                Parity::Even(Even::new_unchecked(self.generation), &self.value.even)
118            }
119        }
120    }
121
122    /// Returns the generation and a mutable reference to the value.
123    #[inline]
124    pub fn as_parity_mut(&mut self) -> Parity<G, &mut T, &mut U> {
125        // SAFETY: the same as in `as_parity`.
126        unsafe {
127            if self.is_odd() {
128                Parity::Odd(Odd::new_unchecked(self.generation), &mut self.value.odd)
129            } else {
130                Parity::Even(Even::new_unchecked(self.generation), &mut self.value.even)
131            }
132        }
133    }
134
135    /// Takes the generation and the value out of the slot.
136    #[inline]
137    pub fn into_parity(self) -> Parity<G, T, U> {
138        let mut slot = ManuallyDrop::new(self);
139        // SAFETY: the parity of the generation says which field is live. That
140        // field's value is taken out once, and the slot is never dropped, so
141        // the value is not dropped a second time.
142        unsafe {
143            if slot.is_odd() {
144                Parity::Odd(
145                    Odd::new_unchecked(slot.generation),
146                    ManuallyDrop::take(&mut slot.value.odd),
147                )
148            } else {
149                Parity::Even(
150                    Even::new_unchecked(slot.generation),
151                    ManuallyDrop::take(&mut slot.value.even),
152                )
153            }
154        }
155    }
156
157    /// Returns a reference to the `T` if the slot's generation is
158    /// `generation`.
159    #[inline]
160    pub fn get_odd(&self, generation: Odd<G>) -> Option<&T> {
161        if self.generation == G::from_non_zero(generation.get()) {
162            // SAFETY: the generation is odd, so `odd` is the live field.
163            Some(unsafe { &self.value.odd })
164        } else {
165            None
166        }
167    }
168
169    /// Returns a mutable reference to the `T` if the slot's generation is
170    /// `generation`.
171    #[inline]
172    pub fn get_odd_mut(&mut self, generation: Odd<G>) -> Option<&mut T> {
173        if self.generation == G::from_non_zero(generation.get()) {
174            // SAFETY: the generation is odd, so `odd` is the live field.
175            Some(unsafe { &mut self.value.odd })
176        } else {
177            None
178        }
179    }
180
181    /// Takes the `T` out of the slot if the slot's generation is
182    /// `generation`.
183    ///
184    /// # Errors
185    ///
186    /// Hands the slot back if its generation is not `generation`.
187    #[inline]
188    pub fn into_odd(self, generation: Odd<G>) -> Result<T, Self> {
189        if self.generation == G::from_non_zero(generation.get()) {
190            let mut slot = ManuallyDrop::new(self);
191            // SAFETY: the generation is odd, so `odd` is the live field, and
192            // the slot is never dropped, so the value is not dropped twice.
193            Ok(unsafe { ManuallyDrop::take(&mut slot.value.odd) })
194        } else {
195            Err(self)
196        }
197    }
198
199    /// Returns a reference to the `U` if the slot's generation is
200    /// `generation`.
201    #[inline]
202    pub fn get_even(&self, generation: Even<G>) -> Option<&U> {
203        if self.generation == generation.get() {
204            // SAFETY: the generation is even, so `even` is the live field.
205            Some(unsafe { &self.value.even })
206        } else {
207            None
208        }
209    }
210
211    /// Returns a mutable reference to the `U` if the slot's generation is
212    /// `generation`.
213    #[inline]
214    pub fn get_even_mut(&mut self, generation: Even<G>) -> Option<&mut U> {
215        if self.generation == generation.get() {
216            // SAFETY: the generation is even, so `even` is the live field.
217            Some(unsafe { &mut self.value.even })
218        } else {
219            None
220        }
221    }
222
223    /// Takes the `U` out of the slot if the slot's generation is
224    /// `generation`.
225    ///
226    /// # Errors
227    ///
228    /// Hands the slot back if its generation is not `generation`.
229    #[inline]
230    pub fn into_even(self, generation: Even<G>) -> Result<U, Self> {
231        if self.generation == generation.get() {
232            let mut slot = ManuallyDrop::new(self);
233            // SAFETY: the generation is even, so `even` is the live field,
234            // and the slot is never dropped, so the value is not dropped
235            // twice.
236            Ok(unsafe { ManuallyDrop::take(&mut slot.value.even) })
237        } else {
238            Err(self)
239        }
240    }
241
242    /// Puts the generation and the value in `parity` into the slot, and
243    /// returns the ones it had before.
244    #[inline]
245    pub fn replace(&mut self, parity: Parity<G, T, U>) -> Parity<G, T, U> {
246        match parity {
247            Parity::Odd(generation, value) => self.set_odd(generation, value),
248            Parity::Even(generation, value) => self.set_even(generation, value),
249        }
250    }
251
252    /// Puts an odd `generation` and a `T` into the slot, and returns the
253    /// generation and the value it had before.
254    #[inline]
255    pub fn set_odd(&mut self, generation: Odd<G>, value: T) -> Parity<G, T, U> {
256        // SAFETY: the old value is moved out of a copy of the slot, and both
257        // fields are overwritten right after, before anything can panic or
258        // drop the slot, so the old value is neither dropped nor used twice.
259        let old = unsafe { ptr::read(self).into_parity() };
260        self.generation = G::from_non_zero(generation.get());
261        self.value.odd = ManuallyDrop::new(value);
262        old
263    }
264
265    /// Puts an even `generation` and a `U` into the slot, and returns the
266    /// generation and the value it had before.
267    #[inline]
268    pub fn set_even(&mut self, generation: Even<G>, value: U) -> Parity<G, T, U> {
269        // SAFETY: the same as in `set_odd`.
270        let old = unsafe { ptr::read(self).into_parity() };
271        self.generation = generation.get();
272        self.value.even = ManuallyDrop::new(value);
273        old
274    }
275
276    /// Moves the `T` out of the slot and puts an even `generation` and a `U`
277    /// in its place.
278    ///
279    /// # Safety
280    ///
281    /// The slot's current generation must be odd.
282    #[inline]
283    pub unsafe fn replace_odd_unchecked(&mut self, generation: Even<G>, value: U) -> T {
284        debug_assert!(self.is_odd());
285        // SAFETY: the caller promises an odd generation, so `odd` is the live
286        // field. It is overwritten right after without being dropped.
287        let old = unsafe { ManuallyDrop::take(&mut self.value.odd) };
288        self.generation = generation.get();
289        self.value.even = ManuallyDrop::new(value);
290        old
291    }
292
293    /// Moves the `U` out of the slot and puts an odd `generation` and a `T`
294    /// in its place.
295    ///
296    /// # Safety
297    ///
298    /// The slot's current generation must be even.
299    #[inline]
300    pub unsafe fn replace_even_unchecked(&mut self, generation: Odd<G>, value: T) -> U {
301        debug_assert!(self.is_even());
302        // SAFETY: the caller promises an even generation, so `even` is the
303        // live field. It is overwritten right after without being dropped.
304        let old = unsafe { ManuallyDrop::take(&mut self.value.even) };
305        self.generation = G::from_non_zero(generation.get());
306        self.value.odd = ManuallyDrop::new(value);
307        old
308    }
309
310    /// Returns a reference to the `T` without checking the generation.
311    ///
312    /// # Safety
313    ///
314    /// The slot's generation must be odd.
315    #[inline]
316    pub unsafe fn get_odd_unchecked(&self) -> &T {
317        debug_assert!(self.is_odd());
318        // SAFETY: the caller promises an odd generation, so `odd` is the
319        // live field.
320        unsafe { &self.value.odd }
321    }
322
323    /// Returns a mutable reference to the `T` without checking the
324    /// generation.
325    ///
326    /// # Safety
327    ///
328    /// The slot's generation must be odd.
329    #[inline]
330    pub unsafe fn get_odd_unchecked_mut(&mut self) -> &mut T {
331        debug_assert!(self.is_odd());
332        // SAFETY: the caller promises an odd generation, so `odd` is the
333        // live field.
334        unsafe { &mut self.value.odd }
335    }
336
337    /// Returns a reference to the `U` without checking the generation.
338    ///
339    /// # Safety
340    ///
341    /// The slot's generation must be even.
342    #[inline]
343    pub unsafe fn get_even_unchecked(&self) -> &U {
344        debug_assert!(self.is_even());
345        // SAFETY: the caller promises an even generation, so `even` is the
346        // live field.
347        unsafe { &self.value.even }
348    }
349
350    /// Returns a mutable reference to the `U` without checking the
351    /// generation.
352    ///
353    /// # Safety
354    ///
355    /// The slot's generation must be even.
356    #[inline]
357    pub unsafe fn get_even_unchecked_mut(&mut self) -> &mut U {
358        debug_assert!(self.is_even());
359        // SAFETY: the caller promises an even generation, so `even` is the
360        // live field.
361        unsafe { &mut self.value.even }
362    }
363}
364
365impl<G: KeyPiece, T, U> Drop for Slot<G, T, U> {
366    #[inline]
367    fn drop(&mut self) {
368        // SAFETY: the parity of the generation says which field is live, and
369        // the slot is not used again after this.
370        unsafe {
371            if self.is_odd() {
372                ManuallyDrop::drop(&mut self.value.odd);
373            } else {
374                ManuallyDrop::drop(&mut self.value.even);
375            }
376        }
377    }
378}
379
380impl<G: KeyPiece, T: Clone, U: Clone> Clone for Slot<G, T, U> {
381    #[inline]
382    fn clone(&self) -> Self {
383        match self.as_parity() {
384            Parity::Odd(generation, value) => Self::new_odd(generation, value.clone()),
385            Parity::Even(generation, value) => Self::new_even(generation, value.clone()),
386        }
387    }
388}
389
390impl<G: KeyPiece, T: fmt::Debug, U: fmt::Debug> fmt::Debug for Slot<G, T, U> {
391    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
392        let value: &dyn fmt::Debug = match self.as_parity() {
393            Parity::Odd(_, value) => value,
394            Parity::Even(_, value) => value,
395        };
396        f.debug_struct("Slot")
397            .field("generation", &self.generation)
398            .field("value", value)
399            .finish()
400    }
401}
402
403mod sealed {
404    /// Keeps [`GenSlotItem`](super::GenSlotItem) and
405    /// [`SecondarySlotItem`](super::SecondarySlotItem) from being implemented
406    /// outside this crate.
407    pub trait Sealed {}
408}
409
410/// Describes the slot a [`GenMap`](crate::GenMap) keeps each of its values in,
411/// for use as a bound in a [`GenMapConfig`](crate::GenMapConfig) impl.
412///
413/// Every value in a map sits in a slot, together with the slot's
414/// generation. The slots of a `GenMap<T, C>` are
415/// [`MapSlot<T, C>`](crate::MapSlot). A config implements `GenMapConfig<S>`
416/// for the slot types `S` it supports, usually for all of them at once with
417/// `impl<S: GenSlotItem> GenMapConfig<S> for YourConfig`. Inside that impl, `S`
418/// is the slot and `S::Value` is the type of the value in it, so for a
419/// `GenMap<T, C>` it is `T`.
420///
421/// Only [`Slot`] implements `GenSlotItem`. The trait is sealed, so no type
422/// outside this crate can implement it.
423///
424/// # Bounds on the value and the slot
425///
426/// A config can limit which maps can use it with bounds on the value type
427/// or on the slot type. A map whose values or slots do not meet the bounds
428/// fails to compile.
429///
430/// A bound on the value limits the value types, as in the example below.
431///
432/// ```
433/// use gen_map::{DefaultKeyConfig, GenMap, GenMapConfig, GenSlotItem, MapConfig};
434///
435/// /// Maps with this config can only hold values that are `Copy`.
436/// struct CopyValues;
437///
438/// impl MapConfig for CopyValues {
439///     type KeyConfig = DefaultKeyConfig;
440/// }
441///
442/// impl<S: GenSlotItem> GenMapConfig<S> for CopyValues
443/// where
444///     S::Value: Copy,
445/// {
446///     type Storage = Vec<S>;
447/// }
448///
449/// let mut map = GenMap::<u32, CopyValues>::new_with_config();
450/// let key = map.insert(5);
451/// assert_eq!(map[key], 5);
452///
453/// // `String` is not `Copy`, so the next line does not compile.
454/// // let map = GenMap::<String, CopyValues>::new_with_config();
455/// ```
456///
457/// To allow only `u32` values, implement `GenMapConfig` only for slots whose
458/// `Value` is `u32`.
459///
460/// ```
461/// use gen_map::{DefaultKeyConfig, GenMap, GenMapConfig, GenSlotItem, MapConfig};
462///
463/// /// Maps with this config can only hold `u32` values.
464/// struct U32Values;
465///
466/// impl MapConfig for U32Values {
467///     type KeyConfig = DefaultKeyConfig;
468/// }
469///
470/// impl<S: GenSlotItem<Value = u32>> GenMapConfig<S> for U32Values {
471///     type Storage = Vec<S>;
472/// }
473///
474/// let mut map = GenMap::<u32, U32Values>::new_with_config();
475/// let key = map.insert(5);
476/// assert_eq!(map[key], 5);
477///
478/// // The values are `u64`, not `u32`, so the next line does not compile.
479/// // let map = GenMap::<u64, U32Values>::new_with_config();
480/// ```
481///
482/// A bound on `S` limits the slots. It is what a config needs when its
483/// storage type requires something of the items it holds, because those
484/// items are slots, not bare values. A slot is `Clone`, `Debug`, `Send` or
485/// `Sync` when its value is, and it is never `Copy`.
486///
487/// ```
488/// use gen_map::{DefaultKeyConfig, GenMap, GenMapConfig, GenSlotItem, SlotStorage, MapConfig};
489///
490/// /// A storage that only holds items that can be cloned. Its `SlotStorage`
491/// /// impl, which forwards every method to the `Vec`, is hidden here.
492/// struct ClonePool<S: Clone>(Vec<S>);
493/// # // SAFETY: every method forwards to the `Vec`.
494/// # unsafe impl<S: Clone> SlotStorage for ClonePool<S> {
495/// #     type Item = S;
496/// #     type Error = ();
497/// #     fn empty() -> Self {
498/// #         ClonePool(Vec::new())
499/// #     }
500/// #     fn with_capacity(capacity: usize) -> Self {
501/// #         ClonePool(Vec::with_capacity(capacity))
502/// #     }
503/// #     fn capacity(&self) -> usize {
504/// #         self.0.capacity()
505/// #     }
506/// #     fn as_slice(&self) -> &[S] {
507/// #         &self.0
508/// #     }
509/// #     fn as_mut_slice(&mut self) -> &mut [S] {
510/// #         &mut self.0
511/// #     }
512/// #     fn ensure_room(&mut self, _additional: usize) -> Result<(), ()> {
513/// #         Ok(())
514/// #     }
515/// #     fn try_push(&mut self, item: S) -> Result<(), S> {
516/// #         self.0.push(item);
517/// #         Ok(())
518/// #     }
519/// #     fn clear(&mut self) {
520/// #         self.0.clear();
521/// #     }
522/// # }
523///
524/// /// Maps with this config need slots that can be cloned, since
525/// /// `ClonePool<S>` needs `S: Clone`.
526/// struct Cloneable;
527///
528/// impl MapConfig for Cloneable {
529///     type KeyConfig = DefaultKeyConfig;
530/// }
531///
532/// impl<S: GenSlotItem + Clone> GenMapConfig<S> for Cloneable {
533///     type Storage = ClonePool<S>;
534/// }
535///
536/// // `String` is `Clone`, so a slot holding one is too.
537/// let mut map = GenMap::<String, Cloneable>::new_with_config();
538/// let key = map.insert("a".to_string());
539/// assert_eq!(map[key], "a");
540///
541/// // `Mutex` is not `Clone`, so neither is a slot holding one, and the next
542/// // line does not compile.
543/// // let map = GenMap::<std::sync::Mutex<u32>, Cloneable>::new_with_config();
544/// ```
545pub trait GenSlotItem: sealed::Sealed {
546    /// The type of the value in the slot. For the slots of a
547    /// `GenMap<T, C>`, it is `T`.
548    type Value;
549}
550
551impl<G: KeyPiece, T, U> sealed::Sealed for Slot<G, T, U> {}
552
553impl<G: KeyPiece, T, U> GenSlotItem for Slot<G, T, U> {
554    type Value = T;
555}
556
557/// Describes the slot a [`SecondaryMap`](crate::SecondaryMap) keeps each of its
558/// values in, for use as a bound in a
559/// [`SecondaryMapConfig`](crate::SecondaryMapConfig) impl. Inside
560/// `impl<S: SecondarySlotItem> SecondaryMapConfig<S> for YourConfig`, `S` is
561/// the slot and `S::Value` is the type of the value in it.
562///
563/// Only [`SecondarySlot`] implements `SecondarySlotItem`. The trait is sealed,
564/// so no type outside this crate can implement it.
565pub trait SecondarySlotItem: sealed::Sealed {
566    /// The type of the value in the slot. For the slots of a
567    /// `SecondaryMap<T, C>`, it is `T`.
568    type Value;
569}
570
571/// The slot a [`SecondaryMap`](crate::SecondaryMap) keeps each of its values
572/// in. It has a generation, and it holds a `T` while the generation is odd
573/// and no value while it is even.
574///
575/// `K` is the key config of the map's keys, and its `Gen` is the slot's
576/// generation type. The slots of a `SecondaryMap<T, C>` are
577/// [`SecondaryMapSlot<T, C>`](crate::SecondaryMapSlot).
578///
579/// # Examples
580///
581/// ```
582/// use gen_map::{DefaultKeyConfig, GenMap, SecondarySlot};
583///
584/// let mut map = GenMap::new();
585/// let key = map.insert("a");
586///
587/// let mut slot = SecondarySlot::<DefaultKeyConfig, u64>::empty();
588/// assert_eq!(slot.get(), None);
589///
590/// assert_eq!(slot.replace(key.generation(), 10), None);
591/// assert_eq!(slot.get(), Some((key.generation(), &10)));
592/// assert_eq!(slot.take(), Some(10));
593/// assert_eq!(slot.get(), None);
594/// ```
595pub struct SecondarySlot<K: KeyConfig, T>(Slot<K::Gen, T, ()>);
596
597impl<K: KeyConfig, T> SecondarySlot<K, T> {
598    /// Creates a slot with generation zero and no value.
599    #[inline]
600    pub fn empty() -> Self {
601        Self(Slot::new_even(Even::ZERO, ()))
602    }
603
604    /// Creates a slot that holds `value` under `generation`.
605    #[inline]
606    pub fn new(generation: Odd<K::Gen>, value: T) -> Self {
607        Self(Slot::new_odd(generation, value))
608    }
609
610    /// Returns the generation and a reference to the value, or `None` if
611    /// the slot is empty.
612    #[inline]
613    pub fn get(&self) -> Option<(Odd<K::Gen>, &T)> {
614        match self.0.as_parity() {
615            Parity::Odd(generation, value) => Some((generation, value)),
616            Parity::Even(..) => None,
617        }
618    }
619
620    /// Returns the generation and a mutable reference to the value, or
621    /// `None` if the slot is empty.
622    #[inline]
623    pub fn get_mut(&mut self) -> Option<(Odd<K::Gen>, &mut T)> {
624        match self.0.as_parity_mut() {
625            Parity::Odd(generation, value) => Some((generation, value)),
626            Parity::Even(..) => None,
627        }
628    }
629
630    /// Returns a reference to the value if the slot's generation is
631    /// `generation`.
632    #[inline]
633    pub fn get_odd(&self, generation: Odd<K::Gen>) -> Option<&T> {
634        self.0.get_odd(generation)
635    }
636
637    /// Returns a mutable reference to the value if the slot's generation is
638    /// `generation`.
639    #[inline]
640    pub fn get_odd_mut(&mut self, generation: Odd<K::Gen>) -> Option<&mut T> {
641        self.0.get_odd_mut(generation)
642    }
643
644    /// Returns the slot's generation. It is odd while the slot holds a value,
645    /// and zero while it holds none, since only [`empty`](Self::empty) and
646    /// [`take`](Self::take) leave a slot without a value.
647    #[inline]
648    pub(crate) fn generation(&self) -> K::Gen {
649        self.0.generation()
650    }
651
652    /// Returns a reference to the value without checking that there is one.
653    ///
654    /// # Safety
655    ///
656    /// The slot must hold a value.
657    #[inline]
658    pub(crate) unsafe fn get_odd_unchecked(&self) -> &T {
659        // SAFETY: the caller promises that the slot holds a value, so its
660        // generation is odd.
661        unsafe { self.0.get_odd_unchecked() }
662    }
663
664    /// Returns a mutable reference to the value without checking that
665    /// there is one.
666    ///
667    /// # Safety
668    ///
669    /// The slot must hold a value.
670    #[inline]
671    pub(crate) unsafe fn get_odd_unchecked_mut(&mut self) -> &mut T {
672        // SAFETY: the caller promises that the slot holds a value, so its
673        // generation is odd.
674        unsafe { self.0.get_odd_unchecked_mut() }
675    }
676
677    /// Takes the generation and the value out of the slot, or returns
678    /// `None` if the slot is empty.
679    #[inline]
680    pub fn into_inner(self) -> Option<(Odd<K::Gen>, T)> {
681        match self.0.into_parity() {
682            Parity::Odd(generation, value) => Some((generation, value)),
683            Parity::Even(..) => None,
684        }
685    }
686
687    /// Puts `value` in the slot under `generation`, and returns the value
688    /// the slot held before, if it held one.
689    #[inline]
690    pub fn replace(&mut self, generation: Odd<K::Gen>, value: T) -> Option<T> {
691        match self.0.set_odd(generation, value) {
692            Parity::Odd(_, old) => Some(old),
693            Parity::Even(..) => None,
694        }
695    }
696
697    /// Takes the value out and leaves the slot empty, with generation zero.
698    /// Returns `None` if the slot was already empty.
699    #[inline]
700    pub fn take(&mut self) -> Option<T> {
701        match self.0.set_even(Even::ZERO, ()) {
702            Parity::Odd(_, value) => Some(value),
703            Parity::Even(..) => None,
704        }
705    }
706}
707
708impl<K: KeyConfig, T: Clone> Clone for SecondarySlot<K, T> {
709    #[inline]
710    fn clone(&self) -> Self {
711        Self(self.0.clone())
712    }
713}
714
715impl<K: KeyConfig, T: fmt::Debug> fmt::Debug for SecondarySlot<K, T> {
716    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
717        f.debug_struct("SecondarySlot")
718            .field("generation", &self.0.generation())
719            .field("value", &self.get().map(|(_, value)| value))
720            .finish()
721    }
722}
723
724impl<K: KeyConfig, T> sealed::Sealed for SecondarySlot<K, T> {}
725
726impl<K: KeyConfig, T> SecondarySlotItem for SecondarySlot<K, T> {
727    type Value = T;
728}