@@ -476,7 +476,7 @@ where
476476{
477477 /// Inserts each `(K, V)` pair into the map by pushing the value into the foreground layer.
478478 ///
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
480480 /// already exists, the current foreground value is moved to the background, and the
481481 /// new value becomes the foreground. If the key is new, it is inserted.
482482 ///
@@ -865,14 +865,12 @@ impl<T> Overlay<T> {
865865 #[ inline]
866866 pub fn pull ( & mut self ) -> Option < T > {
867867 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
870873 }
871-
872- let evicted = unsafe { self . slots [ fgi] . assume_init_read ( ) } ;
873- self . bits &= !( 1 << fgi) ;
874- self . flip_unchecked ( ) ;
875- Some ( evicted)
876874 }
877875
878876 /// Pull the current foreground value without checking if it is present.
@@ -894,10 +892,8 @@ impl<T> Overlay<T> {
894892 #[ inline]
895893 pub fn pull_unchecked ( & mut self ) -> T {
896894 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 ( ) }
901897 }
902898
903899 /// Swap in a new foreground value, returning the old background if present.
@@ -981,12 +977,37 @@ impl<T> Overlay<T> {
981977 /// ```
982978 #[ inline]
983979 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+ }
986983 }
987984
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+ /// ```
9881009 #[ inline]
989- fn flip_unchecked ( & mut self ) {
1010+ pub fn flip_unchecked ( & mut self ) {
9901011 self . bits ^= FG_SLOT ;
9911012 }
9921013
0 commit comments