@@ -476,7 +476,7 @@ where
476
476
{
477
477
/// Inserts each `(K, V)` pair into the map by pushing the value into the foreground layer.
478
478
///
479
- /// This behaves the same as calling [` push`] for each element in the iterator. If a key
479
+ /// This behaves the same as calling push for each element in the iterator. If a key
480
480
/// already exists, the current foreground value is moved to the background, and the
481
481
/// new value becomes the foreground. If the key is new, it is inserted.
482
482
///
@@ -865,14 +865,12 @@ impl<T> Overlay<T> {
865
865
#[ inline]
866
866
pub fn pull ( & mut self ) -> Option < T > {
867
867
let fgi = self . fg_index ( ) ;
868
- if !self . is_slot_present ( fgi) {
869
- return None ;
868
+ if self . is_slot_present ( fgi) {
869
+ self . bits ^= FG_SLOT | ( 1 << fgi) ;
870
+ Some ( unsafe { self . slots [ fgi] . assume_init_read ( ) } )
871
+ } else {
872
+ None
870
873
}
871
-
872
- let evicted = unsafe { self . slots [ fgi] . assume_init_read ( ) } ;
873
- self . bits &= !( 1 << fgi) ;
874
- self . flip_unchecked ( ) ;
875
- Some ( evicted)
876
874
}
877
875
878
876
/// Pull the current foreground value without checking if it is present.
@@ -894,10 +892,8 @@ impl<T> Overlay<T> {
894
892
#[ inline]
895
893
pub fn pull_unchecked ( & mut self ) -> T {
896
894
let fgi = self . fg_index ( ) ;
897
- let evicted = unsafe { self . slots [ fgi] . assume_init_read ( ) } ;
898
- self . bits &= !( 1 << fgi) ;
899
- self . flip_unchecked ( ) ;
900
- evicted
895
+ self . bits ^= FG_SLOT | ( 1 << fgi) ;
896
+ unsafe { self . slots [ fgi] . assume_init_read ( ) }
901
897
}
902
898
903
899
/// Swap in a new foreground value, returning the old background if present.
@@ -981,12 +977,37 @@ impl<T> Overlay<T> {
981
977
/// ```
982
978
#[ inline]
983
979
pub fn flip ( & mut self ) {
984
- let mask = ( ( self . bits & SLOT_MASK ) >> 1 ) & 1 ;
985
- self . bits ^= mask << 2 ;
980
+ if ( self . bits & SLOT_MASK ) == SLOT_MASK {
981
+ self . bits ^= FG_SLOT ;
982
+ }
986
983
}
987
984
985
+ /// Flips the foreground and background slots **without checking** if both are present.
986
+ ///
987
+ /// This is the unchecked, zero-cost variant of [`flip`](Self::flip), intended for internal
988
+ /// or performance-critical use when it is already known that both slots contain valid values.
989
+ ///
990
+ /// This method **does not perform any presence checks**. If one of the slots is uninitialized,
991
+ /// calling this method results in **undefined behavior** when those slots are later accessed.
992
+ ///
993
+ /// # Safety
994
+ ///
995
+ /// The caller must guarantee that:
996
+ ///
997
+ /// - Both slots (foreground and background) are currently initialized.
998
+ /// - A subsequent use of `fg_unchecked` or `bg_unchecked` will not access uninitialized memory.
999
+ ///
1000
+ /// # Example
1001
+ /// ```
1002
+ /// use overlay_map::Overlay;
1003
+ ///
1004
+ /// let mut entry = Overlay::new_both("a", "b");
1005
+ /// entry.flip_unchecked(); // swaps roles without checks
1006
+ /// assert_eq!(entry.fg(), Some(&"b"));
1007
+ /// assert_eq!(entry.bg(), Some(&"a"));
1008
+ /// ```
988
1009
#[ inline]
989
- fn flip_unchecked ( & mut self ) {
1010
+ pub fn flip_unchecked ( & mut self ) {
990
1011
self . bits ^= FG_SLOT ;
991
1012
}
992
1013
0 commit comments