pub fn try_insert_with_key<F, E>(&mut self, f: F) -> Result<K, E>
    where
        F: FnOnce(K) -> Result<V, E>,
    {
        // In case f panics, we don't make any changes until we have the value.
        let new_num_elems = self.num_elems + 1;
        if new_num_elems == core::u32::MAX {
            panic!("HopSlotMap number of elements overflow");
        }

        // All unsafe accesses here are safe due to the invariants of the slot
        // map freelist.
        unsafe {
            let head = self.freelist(0).next;

            // We have a contiguous block of vacant slots starting at head.
            // Put our new element at the back slot.
            let front = head;
            let back = self.freelist(front).other_end;
            let slot_idx = back as usize;

            // Freelist is empty.
            if slot_idx == 0 {
                let version = 1;
                let key = KeyData::new(self.slots.len() as u32, version).into();

                self.slots.push(Slot {
                    u: SlotUnion {
                        value: ManuallyDrop::new(f(key)?),
                    },
                    version,
                });
                self.num_elems = new_num_elems;
                return Ok(key);
            }

            // Compute value first in case f panics or returns an error.
            let occupied_version = self.slots[slot_idx].version | 1;
            let key = KeyData::new(slot_idx as u32, occupied_version).into();
            let value = f(key)?;

            // Update freelist.
            if front == back {
                // Used last slot in this block, move next one to head.
                let new_head = self.freelist(front).next;
                self.freelist(0).next = new_head;
                self.freelist(new_head).prev = 0;
            } else {
                // Continue using this block, only need to update other_ends.
                let new_back = back - 1;
                self.freelist(new_back).other_end = front;
                self.freelist(front).other_end = new_back;
            }

            // And finally insert the value.
            let slot = &mut self.slots[slot_idx];
            slot.version = occupied_version;
            slot.u.value = ManuallyDrop::new(value);
            self.num_elems = new_num_elems;
            Ok(key)
        }
    }
/// Inserts a value given by `f` into the slot map. The key where the
/// value will be stored is passed into `f`. This is useful to store values
/// that contain their own key.
///
/// If `f` returns `Err`, this method returns the error. The slotmap is untouched.
///
/// # Panics
///
/// Panics if the number of elements in the slot map equals
/// 2<sup>32</sup> - 2.
///
/// # Examples
///
/// ```
/// # use slotmap::*;
/// let mut sm = HopSlotMap::new();
/// let key = sm.try_insert_with_key::<_, ()>(|k| Ok((k, 20))).unwrap();
/// assert_eq!(sm[key], (key, 20));
///
/// sm.try_insert_with_key::<_, ()>(|k| Err(())).unwrap_err();
/// ```
Inserts a value given by `f` into the slot map. The key where the
value will be stored is passed into `f`. This is useful to store values
that contain their own key.

If `f` returns `Err`, this method returns the error. The slotmap is untouched.
Inserts a value given by ` f ` into the slot map . The key where the value will be stored is passed into ` f ` . This is useful to store values that contain their own key . If ` f ` returns ` Err ` this method returns the error . The slotmap is untouched .
pub fn try_insert_with_key<F, E>(&mut self, f: F) -> Result<K, E>
    where
        F: FnOnce(K) -> Result<V, E>,
    {
        // In case f panics, we don't make any changes until we have the value.
        let new_num_elems = self.num_elems + 1;
        if new_num_elems == core::u32::MAX {
            panic!("HopSlotMap number of elements overflow");
        }
        // All unsafe accesses here are safe due to the invariants of the slot
        // map freelist.
        unsafe {
            let head = self.freelist(0).next;
            // We have a contiguous block of vacant slots starting at head.
            // Put our new element at the back slot.
            let front = head;
            let back = self.freelist(front).other_end;
            let slot_idx = back as usize;
            // Freelist is empty.
            if slot_idx == 0 {
                let version = 1;
                let key = KeyData::new(self.slots.len() as u32, version).into();
                self.slots.push(Slot {
                    u: SlotUnion {
                        value: ManuallyDrop::new(f(key)?),
                    },
                    version,
                });
                self.num_elems = new_num_elems;
                return Ok(key);
            }
            // Compute value first in case f panics or returns an error.
            let occupied_version = self.slots[slot_idx].version | 1;
            let key = KeyData::new(slot_idx as u32, occupied_version).into();
            let value = f(key)?;
            // Update freelist.
            if front == back {
                // Used last slot in this block, move next one to head.
                let new_head = self.freelist(front).next;
                self.freelist(0).next = new_head;
                self.freelist(new_head).prev = 0;
            } else {
                // Continue using this block, only need to update other_ends.
                let new_back = back - 1;
                self.freelist(new_back).other_end = front;
                self.freelist(front).other_end = new_back;
            }
            // And finally insert the value.
            let slot = &mut self.slots[slot_idx];
            slot.version = occupied_version;
            slot.u.value = ManuallyDrop::new(value);
            self.num_elems = new_num_elems;
            Ok(key)
        }
    }
pub fn try_insert_with_key < F , E > ( & mut self , f : F ) -> Result < K , E > where F : FnOnce ( K ) -> Result < V , E > , { // In case f panics, we don't make any changes until we have the value. let new_num_elems = self . num_elems + 1 ; if new_num_elems == core :: u32 :: MAX { panic ! ( " " ) ; } // All unsafe accesses here are safe due to the invariants of the slot // map freelist. unsafe { let head = self . freelist ( 0 ) . next ; // We have a contiguous block of vacant slots starting at head. // Put our new element at the back slot. let front = head ; let back = self . freelist ( front ) . other_end ; let slot_idx = back as usize ; // Freelist is empty. if slot_idx == 0 { let version = 1 ; let key = KeyData :: new ( self . slots . len ( ) as u32 , version ) . into ( ) ; self . slots . push ( Slot { u : SlotUnion { value : ManuallyDrop :: new ( f ( key ) ? ) , } , version , } ) ; self . num_elems = new_num_elems ; return Ok ( key ) ; } // Compute value first in case f panics or returns an error. let occupied_version = self . slots [ slot_idx ] . version | 1 ; let key = KeyData :: new ( slot_idx as u32 , occupied_version ) . into ( ) ; let value = f ( key ) ? ; // Update freelist. if front == back { // Used last slot in this block, move next one to head. let new_head = self . freelist ( front ) . next ; self . freelist ( 0 ) . next = new_head ; self . freelist ( new_head ) . prev = 0 ; } else { // Continue using this block, only need to update other_ends. let new_back = back - 1 ; self . freelist ( new_back ) . other_end = front ; self . freelist ( front ) . other_end = new_back ; } // And finally insert the value. let slot = & mut self . slots [ slot_idx ] ; slot . version = occupied_version ; slot . u . value = ManuallyDrop :: new ( value ) ; self . num_elems = new_num_elems ; Ok ( key ) } }
Inserts a value given by `f` into the slot map.
Inserts a value given by ` f ` into the slot map .
&mut self
f
F
panics
Panics if the number of elements in the slot map equals
232 - 2.
Panics if the number of elements in the slot map equals 232 - 2 .
examples
None
use slotmap::*;
None