mod entry;
mod impls;
mod iter;
#[cfg(feature = "serde")]
mod serde;
use super::KeyedVecSet;
use alloc::vec::{self, Vec};
use core::borrow::Borrow;
use core::ops::RangeBounds;
pub use self::entry::{Entry, OccupiedEntry, VacantEntry};
pub use self::iter::*;
type Slot<K, V> = (K, V);
#[derive(Clone, Debug)]
pub struct VecMap<K, V> {
pub(crate) base: KeyedVecSet<K, Slot<K, V>>,
}
impl<K, V> VecMap<K, V> {
fn refs(slot: &Slot<K, V>) -> (&K, &V) {
(&slot.0, &slot.1)
}
fn ref_mut(slot: &mut Slot<K, V>) -> (&K, &mut V) {
(&slot.0, &mut slot.1)
}
pub const fn new() -> Self {
VecMap {
base: KeyedVecSet::new(),
}
}
pub fn with_capacity(capacity: usize) -> Self {
VecMap {
base: KeyedVecSet::with_capacity(capacity),
}
}
pub fn capacity(&self) -> usize {
self.base.capacity()
}
pub fn len(&self) -> usize {
self.base.len()
}
pub fn is_empty(&self) -> bool {
self.base.is_empty()
}
pub fn clear(&mut self) {
self.base.clear();
}
pub fn truncate(&mut self, len: usize) {
self.base.truncate(len);
}
pub fn reserve(&mut self, additional: usize) {
self.base.reserve(additional);
}
pub fn retain<F>(&mut self, mut f: F)
where
F: FnMut(&K, &V) -> bool,
{
self.base.retain(|slot| {
let (key, value) = (&slot.0, &slot.1);
f(key, value)
});
}
pub fn shrink_to_fit(&mut self) {
self.base.shrink_to_fit();
}
pub fn shrink_to(&mut self, min_capacity: usize) {
self.base.shrink_to(min_capacity);
}
pub fn split_off(&mut self, at: usize) -> VecMap<K, V> {
VecMap {
base: self.base.split_off(at),
}
}
pub fn drain<R>(&mut self, range: R) -> vec::Drain<'_, (K, V)>
where
R: RangeBounds<usize>,
{
self.base.drain(range)
}
pub fn as_slice(&self) -> &[(K, V)] {
self.base.as_slice()
}
pub fn to_vec(&self) -> Vec<(K, V)>
where
K: Clone,
V: Clone,
{
self.iter().map(|(k, v)| (k.clone(), v.clone())).collect()
}
pub fn into_vec(self) -> Vec<(K, V)> {
self.base.into_vec()
}
pub unsafe fn from_sorted_vec(vec: Vec<(K, V)>) -> Self {
let base = unsafe { KeyedVecSet::from_sorted_vec(vec) };
VecMap { base }
}
pub fn as_mut_keyed_set(&mut self) -> &mut KeyedVecSet<K, (K, V)> {
&mut self.base
}
}
impl<K, V> VecMap<K, V> {
pub fn contains_key<Q>(&self, key: &Q) -> bool
where
K: Borrow<Q> + Ord,
Q: Ord + ?Sized,
{
self.base.contains_key(key)
}
pub fn first(&self) -> Option<(&K, &V)> {
self.base.first().map(Self::refs)
}
pub fn first_mut(&mut self) -> Option<(&K, &mut V)> {
unsafe { self.base.first_mut().map(Self::ref_mut) }
}
pub fn last(&self) -> Option<(&K, &V)> {
self.base.last().map(Self::refs)
}
pub fn last_mut(&mut self) -> Option<(&K, &mut V)> {
unsafe { self.base.last_mut().map(Self::ref_mut) }
}
pub fn get<Q>(&self, key: &Q) -> Option<&V>
where
K: Borrow<Q> + Ord,
Q: Ord + ?Sized,
{
let slot = self.base.get(key)?;
Some(&slot.1)
}
pub fn get_mut<Q>(&mut self, key: &Q) -> Option<&mut V>
where
K: Borrow<Q> + Ord,
Q: Ord + ?Sized,
{
let slot = self.base.get_mut(key)?;
Some(&mut slot.1)
}
pub fn get_index(&self, index: usize) -> Option<(&K, &V)> {
self.base.get_index(index).map(Self::refs)
}
pub fn get_index_mut(&mut self, index: usize) -> Option<(&K, &mut V)> {
unsafe { self.base.get_index_mut(index).map(Self::ref_mut) }
}
pub unsafe fn get_unchecked(&self, index: usize) -> &V {
&unsafe { self.base.get_unchecked(index) }.1
}
pub unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut V {
&mut unsafe { self.base.get_unchecked_mut(index) }.1
}
pub fn get_full<Q>(&self, key: &Q) -> Result<(usize, &K, &V), usize>
where
K: Borrow<Q> + Ord,
Q: Ord + ?Sized,
{
let (idx, slot) = self.base.get_full(key)?;
Ok((idx, &slot.0, &slot.1))
}
pub fn get_full_mut<Q>(&mut self, key: &Q) -> Result<(usize, &K, &mut V), usize>
where
K: Borrow<Q> + Ord,
Q: Ord + ?Sized,
{
let (idx, slot) = unsafe { self.base.get_full_mut(key) }?;
Ok((idx, &slot.0, &mut slot.1))
}
pub fn get_key_value<Q>(&self, key: &Q) -> Option<(&K, &V)>
where
K: Borrow<Q> + Ord,
Q: Ord + ?Sized,
{
self.base.get(key).map(Self::refs)
}
pub fn binary_search<Q>(&self, key: &Q) -> Result<usize, usize>
where
K: Borrow<Q> + Ord,
Q: Ord + ?Sized,
{
self.base.binary_search(key)
}
}
impl<K, V> VecMap<K, V> {
pub fn pop(&mut self) -> Option<(K, V)> {
self.base.pop()
}
pub fn remove<Q>(&mut self, key: &Q) -> Option<V>
where
K: Borrow<Q> + Ord,
Q: Ord + ?Sized,
{
self.base.remove(key).map(|slot| slot.1)
}
pub fn remove_entry<Q>(&mut self, key: &Q) -> Option<(K, V)>
where
K: Borrow<Q> + Ord,
Q: Ord + ?Sized,
{
self.base.remove(key)
}
pub fn remove_index(&mut self, index: usize) -> (K, V) {
self.base.remove_index(index)
}
}
impl<K, V> VecMap<K, V>
where
K: Ord,
{
pub fn insert(&mut self, key: K, value: V) -> Option<V> {
self.insert_full(key, value).1
}
pub fn insert_full(&mut self, key: K, value: V) -> (usize, Option<V>) {
let (index, removed) = self.base.insert_full((key, value));
(index, removed.map(|slot| slot.1))
}
pub fn entry(&mut self, key: K) -> Entry<K, V> {
match self.binary_search(&key) {
Ok(index) => Entry::Occupied(OccupiedEntry::new(self, key, index)),
Err(index) => Entry::Vacant(VacantEntry::new(self, key, index)),
}
}
}
impl<K, V> VecMap<K, V> {
pub fn iter(&self) -> Iter<'_, K, V> {
Iter::new(self.as_slice())
}
pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
IterMut::new(unsafe { self.base.as_mut_slice() })
}
pub fn keys(&self) -> Keys<'_, K, V> {
Keys::new(self.as_slice())
}
pub fn into_keys(self) -> IntoKeys<K, V> {
IntoKeys::new(self.base.into_vec())
}
pub fn values(&self) -> Values<'_, K, V> {
Values::new(self.as_slice())
}
pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> {
ValuesMut::new(unsafe { self.base.as_mut_slice() })
}
pub fn into_values(self) -> IntoValues<K, V> {
IntoValues::new(self.base.into_vec())
}
}
#[test]
fn issue_18() {
use alloc::string::String;
use core::{fmt, mem};
fn test<K, V>(slice: &[(K, V)])
where
K: Clone + Ord + fmt::Debug,
V: Clone + PartialEq + fmt::Debug,
{
assert_eq!(mem::size_of::<Slot<K, V>>(), mem::size_of::<(K, V)>());
assert_eq!(mem::align_of::<Slot<K, V>>(), mem::align_of::<(K, V)>());
let map = VecMap::from(slice);
assert_eq!(map.as_slice(), slice);
}
test(&[(1i64, String::from("foo")), (2, String::from("bar"))]);
test(&[(String::from("bar"), 2), (String::from("foo"), 1i64)]);
test(&[(false, 2), (true, 1i64)]);
test(&[(1i64, true), (2, false)]);
}