//! Densely numbered entity references as mapping keys. use crate::boxed_slice::BoxedSlice; use crate::iter::{IntoIter, Iter, IterMut}; use crate::keys::Keys; use crate::EntityRef; use alloc::boxed::Box; use alloc::vec::Vec; use core::marker::PhantomData; use core::mem; use core::ops::{Index, IndexMut}; use core::slice; #[cfg(feature = "enable-serde")] use serde_derive::{Deserialize, Serialize}; /// A primary mapping `K -> V` allocating dense entity references. /// /// The `PrimaryMap` data structure uses the dense index space to implement a map with a vector. /// /// A primary map contains the main definition of an entity, and it can be used to allocate new /// entity references with the `push` method. /// /// There should only be a single `PrimaryMap` instance for a given `EntityRef` type, otherwise /// conflicting references will be created. Using unknown keys for indexing will cause a panic. /// /// Note that `PrimaryMap` doesn't implement `Deref` or `DerefMut`, which would allow /// `&PrimaryMap` to convert to `&[V]`. One of the main advantages of `PrimaryMap` is /// that it only allows indexing with the distinct `EntityRef` key type, so converting to a /// plain slice would make it easier to use incorrectly. To make a slice of a `PrimaryMap`, use /// `into_boxed_slice`. #[derive(Debug, Clone, Hash, PartialEq, Eq)] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] pub struct PrimaryMap where K: EntityRef, { elems: Vec, unused: PhantomData, } impl PrimaryMap where K: EntityRef, { /// Create a new empty map. pub fn new() -> Self { Self { elems: Vec::new(), unused: PhantomData, } } /// Create a new empty map with the given capacity. pub fn with_capacity(capacity: usize) -> Self { Self { elems: Vec::with_capacity(capacity), unused: PhantomData, } } /// Check if `k` is a valid key in the map. pub fn is_valid(&self, k: K) -> bool { k.index() < self.elems.len() } /// Get the element at `k` if it exists. pub fn get(&self, k: K) -> Option<&V> { self.elems.get(k.index()) } /// Get the element at `k` if it exists, mutable version. pub fn get_mut(&mut self, k: K) -> Option<&mut V> { self.elems.get_mut(k.index()) } /// Is this map completely empty? pub fn is_empty(&self) -> bool { self.elems.is_empty() } /// Get the total number of entity references created. pub fn len(&self) -> usize { self.elems.len() } /// Iterate over all the keys in this map. pub fn keys(&self) -> Keys { Keys::with_len(self.elems.len()) } /// Iterate over all the values in this map. pub fn values(&self) -> slice::Iter { self.elems.iter() } /// Iterate over all the values in this map, mutable edition. pub fn values_mut(&mut self) -> slice::IterMut { self.elems.iter_mut() } /// Iterate over all the keys and values in this map. pub fn iter(&self) -> Iter { Iter::new(self.elems.iter()) } /// Iterate over all the keys and values in this map, mutable edition. pub fn iter_mut(&mut self) -> IterMut { IterMut::new(self.elems.iter_mut()) } /// Remove all entries from this map. pub fn clear(&mut self) { self.elems.clear() } /// Get the key that will be assigned to the next pushed value. pub fn next_key(&self) -> K { K::new(self.elems.len()) } /// Append `v` to the mapping, assigning a new key which is returned. pub fn push(&mut self, v: V) -> K { let k = self.next_key(); self.elems.push(v); k } /// Returns the last element that was inserted in the map. pub fn last(&self) -> Option<(K, &V)> { let len = self.elems.len(); let last = self.elems.last()?; Some((K::new(len - 1), last)) } /// Returns the last element that was inserted in the map. pub fn last_mut(&mut self) -> Option<(K, &mut V)> { let len = self.elems.len(); let last = self.elems.last_mut()?; Some((K::new(len - 1), last)) } /// Reserves capacity for at least `additional` more elements to be inserted. pub fn reserve(&mut self, additional: usize) { self.elems.reserve(additional) } /// Reserves the minimum capacity for exactly `additional` more elements to be inserted. pub fn reserve_exact(&mut self, additional: usize) { self.elems.reserve_exact(additional) } /// Shrinks the capacity of the `PrimaryMap` as much as possible. pub fn shrink_to_fit(&mut self) { self.elems.shrink_to_fit() } /// Consumes this `PrimaryMap` and produces a `BoxedSlice`. pub fn into_boxed_slice(self) -> BoxedSlice { unsafe { BoxedSlice::::from_raw(Box::<[V]>::into_raw(self.elems.into_boxed_slice())) } } /// Returns mutable references to many elements at once. /// /// Returns an error if an element does not exist, or if the same key was passed more than /// once. // This implementation is taken from the unstable `get_many_mut`. // // Once it has been stabilised we can call that method directly. pub fn get_many_mut( &mut self, indices: [K; N], ) -> Result<[&mut V; N], GetManyMutError> { for (i, &idx) in indices.iter().enumerate() { if idx.index() >= self.len() { return Err(GetManyMutError::DoesNotExist(idx)); } for &idx2 in &indices[..i] { if idx == idx2 { return Err(GetManyMutError::MultipleOf(idx)); } } } let slice: *mut V = self.elems.as_mut_ptr(); let mut arr: mem::MaybeUninit<[&mut V; N]> = mem::MaybeUninit::uninit(); let arr_ptr = arr.as_mut_ptr(); unsafe { for i in 0..N { let idx = *indices.get_unchecked(i); *(*arr_ptr).get_unchecked_mut(i) = &mut *slice.add(idx.index()); } Ok(arr.assume_init()) } } /// Performs a binary search on the values with a key extraction function. /// /// Assumes that the values are sorted by the key extracted by the function. /// /// If the value is found then `Ok(K)` is returned, containing the entity key /// of the matching value. /// /// If there are multiple matches, then any one of the matches could be returned. /// /// If the value is not found then Err(K) is returned, containing the entity key /// where a matching element could be inserted while maintaining sorted order. pub fn binary_search_values_by_key<'a, B, F>(&'a self, b: &B, f: F) -> Result where F: FnMut(&'a V) -> B, B: Ord, { self.elems .binary_search_by_key(b, f) .map(|i| K::new(i)) .map_err(|i| K::new(i)) } } #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub enum GetManyMutError { DoesNotExist(K), MultipleOf(K), } impl Default for PrimaryMap where K: EntityRef, { fn default() -> PrimaryMap { PrimaryMap::new() } } /// Immutable indexing into an `PrimaryMap`. /// The indexed value must be in the map. impl Index for PrimaryMap where K: EntityRef, { type Output = V; fn index(&self, k: K) -> &V { &self.elems[k.index()] } } /// Mutable indexing into an `PrimaryMap`. impl IndexMut for PrimaryMap where K: EntityRef, { fn index_mut(&mut self, k: K) -> &mut V { &mut self.elems[k.index()] } } impl IntoIterator for PrimaryMap where K: EntityRef, { type Item = (K, V); type IntoIter = IntoIter; fn into_iter(self) -> Self::IntoIter { IntoIter::new(self.elems.into_iter()) } } impl<'a, K, V> IntoIterator for &'a PrimaryMap where K: EntityRef, { type Item = (K, &'a V); type IntoIter = Iter<'a, K, V>; fn into_iter(self) -> Self::IntoIter { Iter::new(self.elems.iter()) } } impl<'a, K, V> IntoIterator for &'a mut PrimaryMap where K: EntityRef, { type Item = (K, &'a mut V); type IntoIter = IterMut<'a, K, V>; fn into_iter(self) -> Self::IntoIter { IterMut::new(self.elems.iter_mut()) } } impl FromIterator for PrimaryMap where K: EntityRef, { fn from_iter(iter: T) -> Self where T: IntoIterator, { Self { elems: Vec::from_iter(iter), unused: PhantomData, } } } impl From> for PrimaryMap where K: EntityRef, { fn from(elems: Vec) -> Self { Self { elems, unused: PhantomData, } } } #[cfg(test)] mod tests { use super::*; // `EntityRef` impl for testing. #[derive(Clone, Copy, Debug, PartialEq, Eq)] struct E(u32); impl EntityRef for E { fn new(i: usize) -> Self { E(i as u32) } fn index(self) -> usize { self.0 as usize } } #[test] fn basic() { let r0 = E(0); let r1 = E(1); let m = PrimaryMap::::new(); let v: Vec = m.keys().collect(); assert_eq!(v, []); assert!(!m.is_valid(r0)); assert!(!m.is_valid(r1)); } #[test] fn push() { let mut m = PrimaryMap::new(); let k0: E = m.push(12); let k1 = m.push(33); assert_eq!(m[k0], 12); assert_eq!(m[k1], 33); let v: Vec = m.keys().collect(); assert_eq!(v, [k0, k1]); } #[test] fn iter() { let mut m: PrimaryMap = PrimaryMap::new(); m.push(12); m.push(33); let mut i = 0; for (key, value) in &m { assert_eq!(key.index(), i); match i { 0 => assert_eq!(*value, 12), 1 => assert_eq!(*value, 33), _ => panic!(), } i += 1; } i = 0; for (key_mut, value_mut) in m.iter_mut() { assert_eq!(key_mut.index(), i); match i { 0 => assert_eq!(*value_mut, 12), 1 => assert_eq!(*value_mut, 33), _ => panic!(), } i += 1; } } #[test] fn iter_rev() { let mut m: PrimaryMap = PrimaryMap::new(); m.push(12); m.push(33); let mut i = 2; for (key, value) in m.iter().rev() { i -= 1; assert_eq!(key.index(), i); match i { 0 => assert_eq!(*value, 12), 1 => assert_eq!(*value, 33), _ => panic!(), } } i = 2; for (key, value) in m.iter_mut().rev() { i -= 1; assert_eq!(key.index(), i); match i { 0 => assert_eq!(*value, 12), 1 => assert_eq!(*value, 33), _ => panic!(), } } } #[test] fn keys() { let mut m: PrimaryMap = PrimaryMap::new(); m.push(12); m.push(33); let mut i = 0; for key in m.keys() { assert_eq!(key.index(), i); i += 1; } } #[test] fn keys_rev() { let mut m: PrimaryMap = PrimaryMap::new(); m.push(12); m.push(33); let mut i = 2; for key in m.keys().rev() { i -= 1; assert_eq!(key.index(), i); } } #[test] fn values() { let mut m: PrimaryMap = PrimaryMap::new(); m.push(12); m.push(33); let mut i = 0; for value in m.values() { match i { 0 => assert_eq!(*value, 12), 1 => assert_eq!(*value, 33), _ => panic!(), } i += 1; } i = 0; for value_mut in m.values_mut() { match i { 0 => assert_eq!(*value_mut, 12), 1 => assert_eq!(*value_mut, 33), _ => panic!(), } i += 1; } } #[test] fn values_rev() { let mut m: PrimaryMap = PrimaryMap::new(); m.push(12); m.push(33); let mut i = 2; for value in m.values().rev() { i -= 1; match i { 0 => assert_eq!(*value, 12), 1 => assert_eq!(*value, 33), _ => panic!(), } } i = 2; for value_mut in m.values_mut().rev() { i -= 1; match i { 0 => assert_eq!(*value_mut, 12), 1 => assert_eq!(*value_mut, 33), _ => panic!(), } } } #[test] fn from_iter() { let mut m: PrimaryMap = PrimaryMap::new(); m.push(12); m.push(33); let n = m.values().collect::>(); assert!(m.len() == n.len()); for (me, ne) in m.values().zip(n.values()) { assert!(*me == **ne); } } #[test] fn from_vec() { let mut m: PrimaryMap = PrimaryMap::new(); m.push(12); m.push(33); let n = PrimaryMap::::from(m.values().collect::>()); assert!(m.len() == n.len()); for (me, ne) in m.values().zip(n.values()) { assert!(*me == **ne); } } #[test] fn get_many_mut() { let mut m: PrimaryMap = PrimaryMap::new(); let _0 = m.push(0); let _1 = m.push(1); let _2 = m.push(2); assert_eq!([&mut 0, &mut 2], m.get_many_mut([_0, _2]).unwrap()); assert_eq!( m.get_many_mut([_0, _0]), Err(GetManyMutError::MultipleOf(_0)) ); assert_eq!( m.get_many_mut([E(4)]), Err(GetManyMutError::DoesNotExist(E(4))) ); } }