use core::iter::FusedIterator;
use super::{Map, MapMut};
pub trait MapJoin<'a, K: 'a, V>: Iterator<Item = (&'a K, V)> + Sized {
#[inline(always)]
fn cons(self) -> core::iter::Map<Self, fn((&'a K, V)) -> (&'a K, (V, ()))> {
self.map(|(k, v)| (k, (v, ())))
}
#[inline(always)]
fn map_join<M>(self, rhs: &'a M) -> MapJoinIter<Self, &'a M>
where
M: Map<Key = K>,
{
MapJoinIter {
iter: self,
map: rhs,
}
}
#[inline(always)]
fn map_join_left<M>(self, rhs: &'a M) -> MapJoinLeftIter<Self, &'a M>
where
M: Map<Key = K>,
{
MapJoinLeftIter {
iter: self,
map: rhs,
}
}
#[inline(always)]
fn map_join_left_excl<M>(self, rhs: &'a M) -> MapJoinLeftExclIter<Self, &'a M>
where
M: Map<Key = K>,
{
MapJoinLeftExclIter {
iter: self,
map: rhs,
}
}
#[inline(always)]
unsafe fn map_join_mut<M>(self, rhs: &'a mut M) -> MapJoinIter<Self, &'a mut M>
where
M: MapMut<Key = K>,
{
MapJoinIter {
iter: self,
map: rhs,
}
}
#[inline(always)]
unsafe fn map_join_left_mut<M>(self, rhs: &'a mut M) -> MapJoinLeftIter<Self, &'a mut M>
where
M: MapMut<Key = K>,
{
MapJoinLeftIter {
iter: self,
map: rhs,
}
}
}
impl<'a, T, K, V> MapJoin<'a, K, V> for T
where
T: Iterator<Item = (&'a K, V)> + Sized,
K: 'a,
{
}
#[derive(Debug)]
pub struct MapJoinIter<LHS: Iterator, RHS> {
iter: LHS,
map: RHS,
}
impl<'a, K: 'a, V, LHS, RHS> Iterator for MapJoinIter<LHS, &'a RHS>
where
LHS: Iterator<Item = (&'a K, V)>,
RHS: Map<Key = K>,
{
type Item = (&'a K, (&'a RHS::Value, V));
#[inline]
fn next(&mut self) -> Option<Self::Item> {
while let Some((key, lval)) = self.iter.next() {
if let Some(rval) = self.map.get(key) {
return Some((key, (rval, lval)));
}
}
None
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(0, self.iter.size_hint().1)
}
}
impl<'a, K: 'a, V, LHS, RHS> Iterator for MapJoinIter<LHS, &'a mut RHS>
where
LHS: Iterator<Item = (&'a K, V)>,
RHS: MapMut<Key = K>,
{
type Item = (&'a K, (&'a mut RHS::Value, V));
#[inline]
fn next(&mut self) -> Option<Self::Item> {
while let Some((key, lval)) = self.iter.next() {
if let Some(rval) = self.map.get_mut(key) {
let rval = unsafe { &mut *(rval as *mut _) };
return Some((key, (rval, lval)));
}
}
None
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(0, self.iter.size_hint().1)
}
}
impl<LHS, RHS> FusedIterator for MapJoinIter<LHS, RHS>
where
Self: Iterator,
LHS: FusedIterator,
{
}
#[derive(Debug)]
pub struct MapJoinLeftIter<LHS: Iterator, RHS> {
iter: LHS,
map: RHS,
}
impl<'a, K: 'a, V, LHS, RHS> Iterator for MapJoinLeftIter<LHS, &'a RHS>
where
LHS: Iterator<Item = (&'a K, V)>,
RHS: Map<Key = K>,
{
type Item = (&'a K, (Option<&'a RHS::Value>, V));
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.iter
.next()
.map(|(key, lval)| (key, (self.map.get(key), lval)))
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<'a, K: 'a, V, LHS, RHS> Iterator for MapJoinLeftIter<LHS, &'a mut RHS>
where
LHS: Iterator<Item = (&'a K, V)>,
RHS: MapMut<Key = K>,
{
type Item = (&'a K, (Option<&'a mut RHS::Value>, V));
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|(key, lval)| {
let rval = self
.map
.get_mut(key)
.map(|rval| unsafe { &mut *(rval as *mut _) });
(key, (rval, lval))
})
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<LHS, RHS> FusedIterator for MapJoinLeftIter<LHS, RHS>
where
Self: Iterator,
LHS: FusedIterator,
{
}
#[derive(Debug)]
pub struct MapJoinLeftExclIter<LHS: Iterator, RHS> {
iter: LHS,
map: RHS,
}
impl<'a, K: 'a, V, LHS, RHS> Iterator for MapJoinLeftExclIter<LHS, &'a RHS>
where
LHS: Iterator<Item = (&'a K, V)>,
RHS: Map<Key = K>,
{
type Item = LHS::Item;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
while let Some((key, val)) = self.iter.next() {
if !self.map.contains_key(key) {
return Some((key, val));
}
}
None
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(0, self.iter.size_hint().1)
}
}
impl<LHS, RHS> FusedIterator for MapJoinLeftExclIter<LHS, RHS>
where
Self: Iterator,
LHS: FusedIterator,
{
}