#[nougat::gat(Type)]
use super::LendJoin;
#[cfg(feature = "parallel")]
use super::ParJoin;
use super::{Join, RepeatableLendGet};
use hibitset::{BitSetAll, BitSetLike};
use crate::world::Index;
pub struct MaybeJoin<J>(pub J);
#[nougat::gat]
unsafe impl<T> LendJoin for MaybeJoin<T>
where
T: LendJoin,
{
type Mask = BitSetAll;
type Type<'next> = Option<<T as LendJoin>::Type<'next>>;
type Value = (<T as LendJoin>::Mask, <T as LendJoin>::Value);
unsafe fn open(self) -> (Self::Mask, Self::Value) {
let (mask, value) = unsafe { self.0.open() };
(BitSetAll, (mask, value))
}
unsafe fn get<'next>((mask, value): &'next mut Self::Value, id: Index) -> Self::Type<'next> {
if mask.contains(id) {
Some(unsafe { <T as LendJoin>::get(value, id) })
} else {
None
}
}
#[inline]
fn is_unconstrained() -> bool {
true
}
}
unsafe impl<T> RepeatableLendGet for MaybeJoin<T> where T: RepeatableLendGet {}
unsafe impl<T> Join for MaybeJoin<T>
where
T: Join,
{
type Mask = BitSetAll;
type Type = Option<<T as Join>::Type>;
type Value = (<T as Join>::Mask, <T as Join>::Value);
unsafe fn open(self) -> (Self::Mask, Self::Value) {
let (mask, value) = unsafe { self.0.open() };
(BitSetAll, (mask, value))
}
unsafe fn get((mask, value): &mut Self::Value, id: Index) -> Self::Type {
if mask.contains(id) {
Some(unsafe { <T as Join>::get(value, id) })
} else {
None
}
}
#[inline]
fn is_unconstrained() -> bool {
true
}
}
#[cfg(feature = "parallel")]
unsafe impl<T> ParJoin for MaybeJoin<T>
where
T: ParJoin,
{
type Mask = BitSetAll;
type Type = Option<<T as ParJoin>::Type>;
type Value = (<T as ParJoin>::Mask, <T as ParJoin>::Value);
unsafe fn open(self) -> (Self::Mask, Self::Value) {
let (mask, value) = unsafe { self.0.open() };
(BitSetAll, (mask, value))
}
unsafe fn get((mask, value): &Self::Value, id: Index) -> Self::Type {
if mask.contains(id) {
Some(unsafe { <T as ParJoin>::get(value, id) })
} else {
None
}
}
#[inline]
fn is_unconstrained() -> bool {
true
}
}