use super::*;
impl<K: RadixKey, V: Clone + Eq> PartialEq for IdMap<K, V> {
fn eq(&self, other: &IdMap<K, V>) -> bool {
match (&self.0, &other.0) {
(Some(this), Some(other)) => this.rec_eq(other),
(Some(_), None) => false,
(None, Some(_)) => false,
(None, None) => true,
}
}
}
impl<K: RadixKey, V: Clone + Eq> Eq for IdMap<K, V> {}
impl<K: RadixKey, V: Clone> ConsCtx<K, V> for () {
fn cons(&mut self, inner: InnerMap<K, V>) -> Arc<InnerMap<K, V>> {
Arc::new(inner)
}
fn cons_arc(&mut self, inner: &Arc<InnerMap<K, V>>) -> Arc<InnerMap<K, V>> {
inner.clone()
}
fn cons_recursive(&mut self, inner: &Arc<InnerMap<K, V>>) -> Arc<InnerMap<K, V>> {
inner.clone()
}
}
impl<I> RadixKey for I
where
I: Default + Hash + PrimInt + AsPrimitive<u8> + 'static,
u8: AsPrimitive<I>,
{
type PatternType = I;
type DepthType = u8;
#[inline(always)]
fn pattern(&self, _depth: u8) -> I {
*self
}
#[inline(always)]
fn pattern_no(_depth: u8) -> usize {
0
}
}
impl<D, I> Pattern<D> for I
where
I: Default + Hash + PrimInt + AsPrimitive<u8> + 'static,
u8: AsPrimitive<I>,
D: AsPrimitive<u32>,
u8: AsPrimitive<D>,
{
const MAX_BITS: usize = 64;
fn max_bits() -> D {
(64u8).as_()
}
fn byte(self, depth: D) -> u8 {
let depth: u32 = depth.as_();
let max_bits: u32 = <Self as Pattern<D>>::MAX_BITS as u32;
let ix: u32 = (depth / 8) % max_bits;
(self.unsigned_shr(ix * 8) & 0xFF.as_()).as_()
}
fn diff(self, other: I) -> D {
let xor = self ^ other;
let zeroes = xor.trailing_zeros() as u8;
zeroes.as_()
}
}
impl<K: RadixKey, V: Eq + Clone> PartialOrd for IdMap<K, V> {
fn partial_cmp(&self, other: &IdMap<K, V>) -> Option<Ordering> {
self.map_cmp(other, false)
}
fn lt(&self, other: &IdMap<K, V>) -> bool {
self.len() < other.len() && self.is_submap(other, false)
}
fn gt(&self, other: &IdMap<K, V>) -> bool {
self.len() > other.len() && other.is_submap(self, false)
}
fn le(&self, other: &IdMap<K, V>) -> bool {
self.is_submap(other, false)
}
fn ge(&self, other: &IdMap<K, V>) -> bool {
other.is_submap(self, false)
}
}
impl<K: RadixKey, V: Clone> IntoIterator for IdMap<K, V> {
type Item = (K, V);
type IntoIter = IdMapIntoIter<K, V>;
fn into_iter(self) -> IdMapIntoIter<K, V> {
let mut result = IdMapIntoIter::empty();
if let Some(inner) = self.0 {
result.root(inner)
}
result
}
}
impl<K: RadixKey, V: Clone> Default for IdMap<K, V> {
fn default() -> IdMap<K, V> {
IdMap(None)
}
}
impl<K: RadixKey, V: Clone> FromIterator<(K, V)> for IdMap<K, V> {
fn from_iter<I>(iter: I) -> IdMap<K, V>
where
I: IntoIterator<Item = (K, V)>,
{
let mut result = IdMap::new();
for (key, value) in iter {
result.try_insert(key, value);
}
result
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn big_small_submap_check() {
use Ordering::*;
let mut small = IdMap::singleton(3, 12);
let mut big = IdMap::new();
for x in 0..1000 {
big.try_insert(x, 4 * x);
}
assert_eq!(small.partial_cmp(&big), Some(Less));
assert!(small.le(&big));
assert!(!small.ge(&big));
assert!(small.lt(&big));
assert!(!small.gt(&big));
assert_eq!(small.domain_cmp(&big), Some(Less));
small.try_insert(4, 12);
assert_eq!(small.partial_cmp(&big), None);
assert!(!small.le(&big));
assert!(!small.ge(&big));
assert!(!small.lt(&big));
assert!(!small.gt(&big));
assert_eq!(small.domain_cmp(&big), Some(Less));
small.try_insert(1000, 3);
assert_eq!(small.partial_cmp(&big), None);
assert!(!small.le(&big));
assert!(!small.ge(&big));
assert!(!small.lt(&big));
assert!(!small.gt(&big));
assert_eq!(small.domain_cmp(&big), None);
let u1 = big.left_unioned(&small);
assert_eq!(u1.len(), 1001);
assert_eq!(u1.domain_cmp(&big), Some(Greater));
assert_eq!(u1.domain_cmp(&small), Some(Greater));
assert_eq!(u1.partial_cmp(&big), Some(Greater));
assert_eq!(u1.partial_cmp(&small), None);
let u2 = small.left_unioned(&big);
assert_eq!(u2.len(), 1001);
assert_eq!(u2.domain_cmp(&big), Some(Greater));
assert_eq!(u2.domain_cmp(&small), Some(Greater));
assert_eq!(u2.partial_cmp(&big), None);
assert_eq!(u2.partial_cmp(&small), Some(Greater));
}
}