pub struct BiHashMap<T: BiHashItem, S = DefaultHashBuilder, A: Allocator = Global> { /* private fields */ }
Expand description
A 1:1 (bijective) map for two keys and a value.
The storage mechanism is a fast hash table of integer indexes to items, with these indexes stored in two hash tables. This allows for efficient lookups by either of the two keys and prevents duplicates.
§Examples
use iddqd::{BiHashItem, BiHashMap, bi_upcast};
// Define a struct with two keys and a value.
#[derive(Debug, PartialEq, Eq)]
struct MyItem {
id: u32,
name: &'static str,
value: i32,
}
// Implement BiHashItem for the struct.
impl BiHashItem for MyItem {
type K1<'a> = u32;
type K2<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
self.name
}
bi_upcast!();
}
// Create a new BiHashMap and insert items.
let mut map = BiHashMap::new();
map.insert_unique(MyItem { id: 1, name: "foo", value: 42 }).unwrap();
map.insert_unique(MyItem { id: 2, name: "bar", value: 99 }).unwrap();
// Look up by the first key.
assert_eq!(map.get1(&1).unwrap().value, 42);
assert_eq!(map.get1(&2).unwrap().value, 99);
assert!(map.get1(&3).is_none());
// Look up by the second key.
assert_eq!(map.get2(&"foo").unwrap().value, 42);
assert_eq!(map.get2(&"bar").unwrap().value, 99);
assert!(map.get2(&"baz").is_none());
Implementations§
Source§impl<T: BiHashItem> BiHashMap<T>
impl<T: BiHashItem> BiHashMap<T>
Sourcepub fn new() -> Self
pub fn new() -> Self
Creates a new, empty BiHashMap
.
§Examples
use iddqd::{BiHashItem, BiHashMap, bi_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Item {
id: u32,
name: String,
value: i32,
}
impl BiHashItem for Item {
type K1<'a> = u32;
type K2<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.name
}
bi_upcast!();
}
let map: BiHashMap<Item> = BiHashMap::new();
assert!(map.is_empty());
assert_eq!(map.len(), 0);
Sourcepub fn with_capacity(capacity: usize) -> Self
pub fn with_capacity(capacity: usize) -> Self
Creates a new BiHashMap
with the given capacity.
§Examples
use iddqd::{BiHashItem, BiHashMap, bi_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Item {
id: u32,
name: String,
value: i32,
}
impl BiHashItem for Item {
type K1<'a> = u32;
type K2<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.name
}
bi_upcast!();
}
let map: BiHashMap<Item> = BiHashMap::with_capacity(10);
assert!(map.capacity() >= 10);
assert!(map.is_empty());
Source§impl<T: BiHashItem, S: Clone + BuildHasher> BiHashMap<T, S>
impl<T: BiHashItem, S: Clone + BuildHasher> BiHashMap<T, S>
Sourcepub fn with_hasher(hasher: S) -> Self
pub fn with_hasher(hasher: S) -> Self
Creates a new BiHashMap
with the given hasher.
§Examples
use iddqd::{BiHashItem, BiHashMap, bi_upcast};
use std::collections::hash_map::RandomState;
#[derive(Debug, PartialEq, Eq)]
struct Item {
id: u32,
name: String,
value: i32,
}
impl BiHashItem for Item {
type K1<'a> = u32;
type K2<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.name
}
bi_upcast!();
}
let hasher = RandomState::new();
let map: BiHashMap<Item, RandomState> = BiHashMap::with_hasher(hasher);
assert!(map.is_empty());
Sourcepub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> Self
pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> Self
Creates a new BiHashMap
with the given capacity and hasher.
§Examples
use iddqd::{BiHashItem, BiHashMap, bi_upcast};
use std::collections::hash_map::RandomState;
#[derive(Debug, PartialEq, Eq)]
struct Item {
id: u32,
name: String,
value: i32,
}
impl BiHashItem for Item {
type K1<'a> = u32;
type K2<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.name
}
bi_upcast!();
}
let hasher = RandomState::new();
let map: BiHashMap<Item, _> =
BiHashMap::with_capacity_and_hasher(10, hasher);
assert!(map.capacity() >= 10);
assert!(map.is_empty());
Source§impl<T: BiHashItem, A: Clone + Allocator> BiHashMap<T, DefaultHashBuilder, A>
impl<T: BiHashItem, A: Clone + Allocator> BiHashMap<T, DefaultHashBuilder, A>
Sourcepub fn new_in(alloc: A) -> Self
pub fn new_in(alloc: A) -> Self
Creates a new empty BiHashMap
using the given allocator.
Requires the allocator-api2
feature to be enabled.
§Examples
Using the bumpalo
allocator:
use iddqd::{BiHashMap, BiHashItem, bi_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Item {
id: u32,
name: String,
value: i32,
}
impl BiHashItem for Item {
type K1<'a> = u32;
type K2<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.name
}
bi_upcast!();
}
// Define a new allocator.
let bump = bumpalo::Bump::new();
// Create a new BiHashMap using the allocator.
let map: BiHashMap<Item, _, &bumpalo::Bump> = BiHashMap::new_in(&bump);
assert!(map.is_empty());
Sourcepub fn with_capacity_in(capacity: usize, alloc: A) -> Self
pub fn with_capacity_in(capacity: usize, alloc: A) -> Self
Creates an empty BiHashMap
with the specified capacity using the given
allocator.
Requires the allocator-api2
feature to be enabled.
§Examples
Using the bumpalo
allocator:
use iddqd::{BiHashMap, BiHashItem, bi_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Item {
id: u32,
name: String,
value: i32,
}
impl BiHashItem for Item {
type K1<'a> = u32;
type K2<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.name
}
bi_upcast!();
}
// Define a new allocator.
let bump = bumpalo::Bump::new();
// Create a new BiHashMap with capacity using the allocator.
let map: BiHashMap<Item, _, &bumpalo::Bump> = BiHashMap::with_capacity_in(10, &bump);
assert!(map.capacity() >= 10);
assert!(map.is_empty());
Source§impl<T: BiHashItem, S: Clone + BuildHasher, A: Clone + Allocator> BiHashMap<T, S, A>
impl<T: BiHashItem, S: Clone + BuildHasher, A: Clone + Allocator> BiHashMap<T, S, A>
Sourcepub fn with_hasher_in(hasher: S, alloc: A) -> Self
pub fn with_hasher_in(hasher: S, alloc: A) -> Self
Creates a new, empty BiHashMap
with the given hasher and allocator.
Requires the allocator-api2
feature to be enabled.
§Examples
Using the bumpalo
allocator:
use iddqd::{BiHashItem, BiHashMap, bi_upcast};
use std::collections::hash_map::RandomState;
#[derive(Debug, PartialEq, Eq)]
struct Item {
id: u32,
name: String,
value: i32,
}
impl BiHashItem for Item {
type K1<'a> = u32;
type K2<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.name
}
bi_upcast!();
}
// Define a new allocator.
let bump = bumpalo::Bump::new();
let hasher = RandomState::new();
// Create a new BiHashMap with hasher using the allocator.
let map: BiHashMap<Item, _, &bumpalo::Bump> =
BiHashMap::with_hasher_in(hasher, &bump);
assert!(map.is_empty());
Sourcepub fn with_capacity_and_hasher_in(capacity: usize, hasher: S, alloc: A) -> Self
pub fn with_capacity_and_hasher_in(capacity: usize, hasher: S, alloc: A) -> Self
Creates a new, empty BiHashMap
with the given capacity, hasher, and
allocator.
Requires the allocator-api2
feature to be enabled.
§Examples
Using the bumpalo
allocator:
use iddqd::{BiHashItem, BiHashMap, bi_upcast};
use std::collections::hash_map::RandomState;
#[derive(Debug, PartialEq, Eq)]
struct Item {
id: u32,
name: String,
value: i32,
}
impl BiHashItem for Item {
type K1<'a> = u32;
type K2<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.name
}
bi_upcast!();
}
// Define a new allocator.
let bump = bumpalo::Bump::new();
let hasher = RandomState::new();
// Create a new BiHashMap with capacity and hasher using the allocator.
let map: BiHashMap<Item, _, &bumpalo::Bump> =
BiHashMap::with_capacity_and_hasher_in(10, hasher, &bump);
assert!(map.capacity() >= 10);
assert!(map.is_empty());
Source§impl<T: BiHashItem, S: Clone + BuildHasher, A: Allocator> BiHashMap<T, S, A>
impl<T: BiHashItem, S: Clone + BuildHasher, A: Allocator> BiHashMap<T, S, A>
Sourcepub fn allocator(&self) -> &A
pub fn allocator(&self) -> &A
Returns the allocator.
Requires the allocator-api2
feature to be enabled.
§Examples
Using the bumpalo
allocator:
use iddqd::{BiHashMap, BiHashItem, bi_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Item {
id: u32,
name: String,
value: i32,
}
impl BiHashItem for Item {
type K1<'a> = u32;
type K2<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.name
}
bi_upcast!();
}
// Define a new allocator.
let bump = bumpalo::Bump::new();
// Create a new BiHashMap using the allocator.
let map: BiHashMap<Item, _, &bumpalo::Bump> = BiHashMap::new_in(&bump);
let _allocator = map.allocator();
Sourcepub fn capacity(&self) -> usize
pub fn capacity(&self) -> usize
Returns the currently allocated capacity of the map.
§Examples
use iddqd::{BiHashItem, BiHashMap, bi_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Item {
id: u32,
name: String,
value: i32,
}
impl BiHashItem for Item {
type K1<'a> = u32;
type K2<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.name
}
bi_upcast!();
}
let map: BiHashMap<Item> = BiHashMap::with_capacity(10);
assert!(map.capacity() >= 10);
let empty_map: BiHashMap<Item> = BiHashMap::new();
assert!(empty_map.capacity() >= 0);
Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Returns true if the map contains no items.
§Examples
use iddqd::{BiHashItem, BiHashMap, bi_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Item {
id: u32,
name: String,
value: i32,
}
impl BiHashItem for Item {
type K1<'a> = u32;
type K2<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.name
}
bi_upcast!();
}
let mut map = BiHashMap::new();
assert!(map.is_empty());
map.insert_unique(Item { id: 1, name: "foo".to_string(), value: 42 })
.unwrap();
assert!(!map.is_empty());
Sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Returns the number of items in the map.
§Examples
use iddqd::{BiHashItem, BiHashMap, bi_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Item {
id: u32,
name: String,
value: i32,
}
impl BiHashItem for Item {
type K1<'a> = u32;
type K2<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.name
}
bi_upcast!();
}
let mut map = BiHashMap::new();
assert_eq!(map.len(), 0);
map.insert_unique(Item { id: 1, name: "foo".to_string(), value: 42 })
.unwrap();
map.insert_unique(Item { id: 2, name: "bar".to_string(), value: 99 })
.unwrap();
assert_eq!(map.len(), 2);
Sourcepub fn iter(&self) -> Iter<'_, T> ⓘ
pub fn iter(&self) -> Iter<'_, T> ⓘ
Returns an iterator over all items in the map.
Similar to HashMap
, the iteration order is arbitrary and not
guaranteed to be stable.
§Examples
use iddqd::{BiHashItem, BiHashMap, bi_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Item {
id: u32,
name: String,
value: i32,
}
impl BiHashItem for Item {
type K1<'a> = u32;
type K2<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.name
}
bi_upcast!();
}
let mut map = BiHashMap::new();
map.insert_unique(Item { id: 1, name: "foo".to_string(), value: 42 })
.unwrap();
map.insert_unique(Item { id: 2, name: "bar".to_string(), value: 99 })
.unwrap();
let mut values: Vec<i32> = map.iter().map(|item| item.value).collect();
values.sort();
assert_eq!(values, vec![42, 99]);
Sourcepub fn iter_mut(&mut self) -> IterMut<'_, T, S, A> ⓘ
pub fn iter_mut(&mut self) -> IterMut<'_, T, S, A> ⓘ
Iterates over the items in the map, allowing for mutation.
Similar to HashMap
, the iteration order is arbitrary and not
guaranteed to be stable.
§Examples
use iddqd::{BiHashItem, BiHashMap, bi_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Item {
id: u32,
name: String,
value: i32,
}
impl BiHashItem for Item {
type K1<'a> = u32;
type K2<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.name
}
bi_upcast!();
}
let mut map = BiHashMap::new();
map.insert_unique(Item { id: 1, name: "foo".to_string(), value: 42 })
.unwrap();
map.insert_unique(Item { id: 2, name: "bar".to_string(), value: 99 })
.unwrap();
for mut item in map.iter_mut() {
item.value += 10;
}
assert_eq!(map.get1(&1).unwrap().value, 52);
assert_eq!(map.get1(&2).unwrap().value, 109);
Sourcepub fn insert_overwrite(&mut self, value: T) -> Vec<T>
pub fn insert_overwrite(&mut self, value: T) -> Vec<T>
Inserts a value into the map, removing any conflicting items and returning a list of those items.
§Examples
use iddqd::{BiHashItem, BiHashMap, bi_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Item {
id: u32,
name: String,
value: i32,
}
impl BiHashItem for Item {
type K1<'a> = u32;
type K2<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.name
}
bi_upcast!();
}
let mut map = BiHashMap::new();
map.insert_unique(Item { id: 1, name: "foo".to_string(), value: 42 })
.unwrap();
map.insert_unique(Item { id: 2, name: "bar".to_string(), value: 99 })
.unwrap();
// Insert an item with conflicting key1
let removed = map.insert_overwrite(Item {
id: 1,
name: "baz".to_string(),
value: 100,
});
assert_eq!(removed.len(), 1);
assert_eq!(removed[0].name, "foo");
assert_eq!(removed[0].value, 42);
assert_eq!(map.len(), 2);
assert_eq!(map.get1(&1).unwrap().name, "baz");
Sourcepub fn insert_unique(&mut self, value: T) -> Result<(), DuplicateItem<T, &T>>
pub fn insert_unique(&mut self, value: T) -> Result<(), DuplicateItem<T, &T>>
Inserts a value into the set, returning an error if any duplicates were added.
§Examples
use iddqd::{BiHashItem, BiHashMap, bi_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Item {
id: u32,
name: String,
value: i32,
}
impl BiHashItem for Item {
type K1<'a> = u32;
type K2<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.name
}
bi_upcast!();
}
let mut map = BiHashMap::new();
// Successful insertion
assert!(
map.insert_unique(Item { id: 1, name: "foo".to_string(), value: 42 })
.is_ok()
);
assert!(
map.insert_unique(Item { id: 2, name: "bar".to_string(), value: 99 })
.is_ok()
);
// Duplicate key1
assert!(
map.insert_unique(Item { id: 1, name: "baz".to_string(), value: 100 })
.is_err()
);
// Duplicate key2
assert!(
map.insert_unique(Item { id: 3, name: "foo".to_string(), value: 200 })
.is_err()
);
Sourcepub fn contains_key_unique<'a, Q1, Q2>(&'a self, key1: &Q1, key2: &Q2) -> bool
pub fn contains_key_unique<'a, Q1, Q2>(&'a self, key1: &Q1, key2: &Q2) -> bool
Returns true if the map contains a single item that matches both key1
and key2
.
§Examples
use iddqd::{BiHashItem, BiHashMap, bi_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Item {
id: u32,
name: String,
value: i32,
}
impl BiHashItem for Item {
type K1<'a> = u32;
type K2<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.name
}
bi_upcast!();
}
let mut map = BiHashMap::new();
map.insert_unique(Item { id: 1, name: "foo".to_string(), value: 42 }).unwrap();
map.insert_unique(Item { id: 2, name: "bar".to_string(), value: 99 }).unwrap();
assert!(map.contains_key_unique(&1, &"foo"));
assert!(map.contains_key_unique(&2, &"bar"));
assert!(!map.contains_key_unique(&1, &"bar")); // key1 exists but key2 doesn't match
assert!(!map.contains_key_unique(&3, &"baz")); // neither key exists
Sourcepub fn get_unique<'a, Q1, Q2>(&'a self, key1: &Q1, key2: &Q2) -> Option<&'a T>
pub fn get_unique<'a, Q1, Q2>(&'a self, key1: &Q1, key2: &Q2) -> Option<&'a T>
Gets a reference to the unique item associated with the given key1
and
key2
, if it exists.
§Examples
use iddqd::{BiHashItem, BiHashMap, bi_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Item {
id: u32,
name: String,
value: i32,
}
impl BiHashItem for Item {
type K1<'a> = u32;
type K2<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.name
}
bi_upcast!();
}
let mut map = BiHashMap::new();
map.insert_unique(Item { id: 1, name: "foo".to_string(), value: 42 }).unwrap();
map.insert_unique(Item { id: 2, name: "bar".to_string(), value: 99 }).unwrap();
assert_eq!(map.get_unique(&1, &"foo").unwrap().value, 42);
assert_eq!(map.get_unique(&2, &"bar").unwrap().value, 99);
assert!(map.get_unique(&1, &"bar").is_none()); // key1 exists but key2 doesn't match
assert!(map.get_unique(&3, &"baz").is_none()); // neither key exists
Sourcepub fn get_mut_unique<'a, Q1, Q2>(
&'a mut self,
key1: &Q1,
key2: &Q2,
) -> Option<RefMut<'a, T, S>>
pub fn get_mut_unique<'a, Q1, Q2>( &'a mut self, key1: &Q1, key2: &Q2, ) -> Option<RefMut<'a, T, S>>
Gets a mutable reference to the unique item associated with the given
key1
and key2
, if it exists.
Sourcepub fn remove_unique<'a, Q1, Q2>(
&'a mut self,
key1: &Q1,
key2: &Q2,
) -> Option<T>
pub fn remove_unique<'a, Q1, Q2>( &'a mut self, key1: &Q1, key2: &Q2, ) -> Option<T>
Removes the item uniquely identified by key1
and key2
, if it exists.
Sourcepub fn contains_key1<'a, Q>(&'a self, key1: &Q) -> bool
pub fn contains_key1<'a, Q>(&'a self, key1: &Q) -> bool
Returns true if the map contains the given key1
.
§Examples
use iddqd::{BiHashItem, BiHashMap, bi_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Item {
id: u32,
name: String,
value: i32,
}
impl BiHashItem for Item {
type K1<'a> = u32;
type K2<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.name
}
bi_upcast!();
}
let mut map = BiHashMap::new();
map.insert_unique(Item { id: 1, name: "foo".to_string(), value: 42 })
.unwrap();
map.insert_unique(Item { id: 2, name: "bar".to_string(), value: 99 })
.unwrap();
assert!(map.contains_key1(&1));
assert!(map.contains_key1(&2));
assert!(!map.contains_key1(&3));
Sourcepub fn get1<'a, Q>(&'a self, key1: &Q) -> Option<&'a T>
pub fn get1<'a, Q>(&'a self, key1: &Q) -> Option<&'a T>
Gets a reference to the value associated with the given key1
.
§Examples
use iddqd::{BiHashItem, BiHashMap, bi_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Item {
id: u32,
name: String,
value: i32,
}
impl BiHashItem for Item {
type K1<'a> = u32;
type K2<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.name
}
bi_upcast!();
}
let mut map = BiHashMap::new();
map.insert_unique(Item { id: 1, name: "foo".to_string(), value: 42 })
.unwrap();
map.insert_unique(Item { id: 2, name: "bar".to_string(), value: 99 })
.unwrap();
assert_eq!(map.get1(&1).unwrap().value, 42);
assert_eq!(map.get1(&2).unwrap().value, 99);
assert!(map.get1(&3).is_none());
Sourcepub fn get1_mut<'a, Q>(&'a mut self, key1: &Q) -> Option<RefMut<'a, T, S>>
pub fn get1_mut<'a, Q>(&'a mut self, key1: &Q) -> Option<RefMut<'a, T, S>>
Gets a mutable reference to the value associated with the given key1
.
Sourcepub fn remove1<'a, Q>(&'a mut self, key1: &Q) -> Option<T>
pub fn remove1<'a, Q>(&'a mut self, key1: &Q) -> Option<T>
Removes an item from the map by its key1
.
§Examples
use iddqd::{BiHashItem, BiHashMap, bi_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Item {
id: u32,
name: String,
value: i32,
}
impl BiHashItem for Item {
type K1<'a> = u32;
type K2<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.name
}
bi_upcast!();
}
let mut map = BiHashMap::new();
map.insert_unique(Item { id: 1, name: "foo".to_string(), value: 42 })
.unwrap();
map.insert_unique(Item { id: 2, name: "bar".to_string(), value: 99 })
.unwrap();
let removed = map.remove1(&1);
assert_eq!(removed.unwrap().value, 42);
assert_eq!(map.len(), 1);
assert!(map.get1(&1).is_none());
assert!(map.remove1(&3).is_none());
Sourcepub fn contains_key2<'a, Q>(&'a self, key2: &Q) -> bool
pub fn contains_key2<'a, Q>(&'a self, key2: &Q) -> bool
Returns true if the map contains the given key2
.
§Examples
use iddqd::{BiHashItem, BiHashMap, bi_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Item {
id: u32,
name: String,
value: i32,
}
impl BiHashItem for Item {
type K1<'a> = u32;
type K2<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.name
}
bi_upcast!();
}
let mut map = BiHashMap::new();
map.insert_unique(Item { id: 1, name: "foo".to_string(), value: 42 })
.unwrap();
map.insert_unique(Item { id: 2, name: "bar".to_string(), value: 99 })
.unwrap();
assert!(map.contains_key2(&"foo"));
assert!(map.contains_key2(&"bar"));
assert!(!map.contains_key2(&"baz"));
Sourcepub fn get2<'a, Q>(&'a self, key2: &Q) -> Option<&'a T>
pub fn get2<'a, Q>(&'a self, key2: &Q) -> Option<&'a T>
Gets a reference to the value associated with the given key2
.
§Examples
use iddqd::{BiHashItem, BiHashMap, bi_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Item {
id: u32,
name: String,
value: i32,
}
impl BiHashItem for Item {
type K1<'a> = u32;
type K2<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.name
}
bi_upcast!();
}
let mut map = BiHashMap::new();
map.insert_unique(Item { id: 1, name: "foo".to_string(), value: 42 })
.unwrap();
map.insert_unique(Item { id: 2, name: "bar".to_string(), value: 99 })
.unwrap();
assert_eq!(map.get2(&"foo").unwrap().value, 42);
assert_eq!(map.get2(&"bar").unwrap().value, 99);
assert!(map.get2(&"baz").is_none());
Sourcepub fn get2_mut<'a, Q>(&'a mut self, key2: &Q) -> Option<RefMut<'a, T, S>>
pub fn get2_mut<'a, Q>(&'a mut self, key2: &Q) -> Option<RefMut<'a, T, S>>
Gets a mutable reference to the value associated with the given key2
.
§Examples
use iddqd::{BiHashItem, BiHashMap, bi_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Item {
id: u32,
name: String,
value: i32,
}
impl BiHashItem for Item {
type K1<'a> = u32;
type K2<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.name
}
bi_upcast!();
}
let mut map = BiHashMap::new();
map.insert_unique(Item { id: 1, name: "foo".to_string(), value: 42 })
.unwrap();
if let Some(mut item_ref) = map.get2_mut(&"foo") {
item_ref.value = 100;
}
assert_eq!(map.get2(&"foo").unwrap().value, 100);
Sourcepub fn remove2<'a, Q>(&'a mut self, key2: &Q) -> Option<T>
pub fn remove2<'a, Q>(&'a mut self, key2: &Q) -> Option<T>
Removes an item from the map by its key2
.
§Examples
use iddqd::{BiHashItem, BiHashMap, bi_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Item {
id: u32,
name: String,
value: i32,
}
impl BiHashItem for Item {
type K1<'a> = u32;
type K2<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.name
}
bi_upcast!();
}
let mut map = BiHashMap::new();
map.insert_unique(Item { id: 1, name: "foo".to_string(), value: 42 })
.unwrap();
map.insert_unique(Item { id: 2, name: "bar".to_string(), value: 99 })
.unwrap();
let removed = map.remove2(&"foo");
assert_eq!(removed.unwrap().value, 42);
assert_eq!(map.len(), 1);
assert!(map.get2(&"foo").is_none());
assert!(map.remove2(&"baz").is_none());
Sourcepub fn entry<'a>(
&'a mut self,
key1: T::K1<'_>,
key2: T::K2<'_>,
) -> Entry<'a, T, S, A>
pub fn entry<'a>( &'a mut self, key1: T::K1<'_>, key2: T::K2<'_>, ) -> Entry<'a, T, S, A>
Retrieves an entry by its keys.
Due to borrow checker limitations, this always accepts owned keys rather than a borrowed form of them.
§Examples
use iddqd::{BiHashItem, BiHashMap, bi_hash_map, bi_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Item {
id: u32,
name: String,
value: i32,
}
impl BiHashItem for Item {
type K1<'a> = u32;
type K2<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.name
}
bi_upcast!();
}
let mut map = BiHashMap::new();
map.insert_unique(Item { id: 1, name: "foo".to_string(), value: 42 })
.unwrap();
// Get existing entry
match map.entry(1, "foo") {
bi_hash_map::Entry::Occupied(entry) => {
assert_eq!(entry.get().as_unique().unwrap().value, 42);
}
bi_hash_map::Entry::Vacant(_) => panic!("Should be occupied"),
}
// Try to get a non-existing entry
match map.entry(2, "bar") {
bi_hash_map::Entry::Occupied(_) => panic!("Should be vacant"),
bi_hash_map::Entry::Vacant(entry) => {
entry.insert(Item { id: 2, name: "bar".to_string(), value: 99 });
}
}
assert_eq!(map.len(), 2);
Trait Implementations§
Source§impl<T: BiHashItem, S: Clone + BuildHasher, A: Allocator> Extend<T> for BiHashMap<T, S, A>
The Extend
implementation overwrites duplicates. In the future, there will
also be an extend_unique
method that will return an error.
impl<T: BiHashItem, S: Clone + BuildHasher, A: Allocator> Extend<T> for BiHashMap<T, S, A>
The Extend
implementation overwrites duplicates. In the future, there will
also be an extend_unique
method that will return an error.
§Examples
use iddqd::{BiHashItem, BiHashMap, bi_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Item {
id: u32,
name: String,
value: i32,
}
impl BiHashItem for Item {
type K1<'a> = u32;
type K2<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.name
}
bi_upcast!();
}
let mut map = BiHashMap::new();
map.insert_unique(Item { id: 1, name: "foo".to_string(), value: 42 }).unwrap();
let new_items = vec![
Item { id: 2, name: "bar".to_string(), value: 99 },
Item { id: 1, name: "baz".to_string(), value: 100 }, // overwrites existing
];
map.extend(new_items);
assert_eq!(map.len(), 2);
assert_eq!(map.get1(&1).unwrap().name, "baz"); // overwritten
assert_eq!(map.get1(&1).unwrap().value, 100);
Source§fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I)
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I)
Source§fn extend_one(&mut self, item: A)
fn extend_one(&mut self, item: A)
extend_one
)Source§fn extend_reserve(&mut self, additional: usize)
fn extend_reserve(&mut self, additional: usize)
extend_one
)Source§impl<T: BiHashItem, S: Clone + BuildHasher + Default, A: Default + Allocator> FromIterator<T> for BiHashMap<T, S, A>
The FromIterator
implementation for BiHashMap
overwrites duplicate
items.
impl<T: BiHashItem, S: Clone + BuildHasher + Default, A: Default + Allocator> FromIterator<T> for BiHashMap<T, S, A>
The FromIterator
implementation for BiHashMap
overwrites duplicate
items.
§Examples
use iddqd::{BiHashItem, BiHashMap, bi_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Item {
id: u32,
name: String,
value: i32,
}
impl BiHashItem for Item {
type K1<'a> = u32;
type K2<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.name
}
bi_upcast!();
}
let items = vec![
Item { id: 1, name: "foo".to_string(), value: 42 },
Item { id: 2, name: "bar".to_string(), value: 99 },
Item { id: 1, name: "baz".to_string(), value: 100 }, // overwrites first item
];
let map: BiHashMap<Item> = items.into_iter().collect();
assert_eq!(map.len(), 2);
assert_eq!(map.get1(&1).unwrap().name, "baz"); // overwritten
assert_eq!(map.get1(&1).unwrap().value, 100);
assert_eq!(map.get1(&2).unwrap().value, 99);
Source§fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self
Source§impl<'a, T: BiHashItem, S: Clone + BuildHasher, A: Allocator> IntoIterator for &'a BiHashMap<T, S, A>
impl<'a, T: BiHashItem, S: Clone + BuildHasher, A: Allocator> IntoIterator for &'a BiHashMap<T, S, A>
Source§impl<'a, T: BiHashItem, S: Clone + BuildHasher, A: Allocator> IntoIterator for &'a mut BiHashMap<T, S, A>
impl<'a, T: BiHashItem, S: Clone + BuildHasher, A: Allocator> IntoIterator for &'a mut BiHashMap<T, S, A>
Source§impl<T: BiHashItem, S: Clone + BuildHasher, A: Allocator> IntoIterator for BiHashMap<T, S, A>
impl<T: BiHashItem, S: Clone + BuildHasher, A: Allocator> IntoIterator for BiHashMap<T, S, A>
Source§impl<T: BiHashItem + PartialEq, S: Clone + BuildHasher, A: Allocator> PartialEq for BiHashMap<T, S, A>
The PartialEq
implementation for BiHashMap
checks that both maps have
the same items, regardless of insertion order.
impl<T: BiHashItem + PartialEq, S: Clone + BuildHasher, A: Allocator> PartialEq for BiHashMap<T, S, A>
The PartialEq
implementation for BiHashMap
checks that both maps have
the same items, regardless of insertion order.
§Examples
use iddqd::{BiHashItem, BiHashMap, bi_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Item {
id: u32,
name: String,
value: i32,
}
impl BiHashItem for Item {
type K1<'a> = u32;
type K2<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.name
}
bi_upcast!();
}
let mut map1 = BiHashMap::new();
map1.insert_unique(Item { id: 1, name: "foo".to_string(), value: 42 })
.unwrap();
map1.insert_unique(Item { id: 2, name: "bar".to_string(), value: 99 })
.unwrap();
let mut map2 = BiHashMap::new();
map2.insert_unique(Item { id: 2, name: "bar".to_string(), value: 99 })
.unwrap();
map2.insert_unique(Item { id: 1, name: "foo".to_string(), value: 42 })
.unwrap();
// Maps are equal even if items were inserted in different order
assert_eq!(map1, map2);
map2.insert_unique(Item { id: 3, name: "baz".to_string(), value: 200 })
.unwrap();
assert_ne!(map1, map2);
impl<T: BiHashItem + Eq, S: Clone + BuildHasher, A: Allocator> Eq for BiHashMap<T, S, A>
Auto Trait Implementations§
impl<T, S, A> Freeze for BiHashMap<T, S, A>
impl<T, S, A> RefUnwindSafe for BiHashMap<T, S, A>
impl<T, S, A> Send for BiHashMap<T, S, A>
impl<T, S, A> Sync for BiHashMap<T, S, A>
impl<T, S, A> Unpin for BiHashMap<T, S, A>
impl<T, S, A> UnwindSafe for BiHashMap<T, S, A>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key
and return true
if they are equal.