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}