use std::ops::BitOrAssign;
use vortex_buffer::Buffer;
use vortex_buffer::BufferMut;
use vortex_compute::lane_kernels::IndexedSource;
use vortex_compute::lane_kernels::IndexedSourceExt;
use vortex_mask::AllOr;
use vortex_mask::Mask;
pub(super) trait Failure: Copy + Default + PartialEq + BitOrAssign {}
impl Failure for bool {}
impl Failure for u8 {}
impl Failure for u16 {}
impl Failure for u32 {}
impl Failure for u64 {}
#[inline]
pub(super) fn checked_lanes<S, T, Apply>(
source: S,
valid_rows: &Mask,
apply: Apply,
) -> Result<Buffer<T>, usize>
where
S: IndexedSource,
T: Copy + Default,
Apply: FnMut(S::Item) -> Option<T>,
{
let len = source.len();
debug_assert_eq!(len, valid_rows.len());
let valid_bits = match valid_rows.bit_buffer() {
AllOr::All => None,
AllOr::None => return Ok(Buffer::zeroed(len)),
AllOr::Some(valid_bits) => Some(valid_bits),
};
let mut values = BufferMut::<T>::with_capacity(len);
let out = &mut values.spare_capacity_mut()[..len];
match valid_bits {
None => source.try_map_into(out, apply)?,
Some(valid_bits) => source.try_map_masked_into(valid_bits, out, apply)?,
}
unsafe { values.set_len(len) };
Ok(values.freeze())
}
#[inline]
pub(super) fn checked_apply_lanes<S, T, Fail, Apply>(
source: S,
valid_rows: &Mask,
mut apply: Apply,
) -> Result<Buffer<T>, usize>
where
S: IndexedSource + Copy,
T: Copy + Default,
Fail: Failure,
Apply: FnMut(S::Item) -> (T, Fail),
{
let len = source.len();
debug_assert_eq!(len, valid_rows.len());
let valid_bits = match valid_rows.bit_buffer() {
AllOr::All => None,
AllOr::None => return Ok(Buffer::zeroed(len)),
AllOr::Some(valid_bits) => Some(valid_bits),
};
let mut values = BufferMut::<T>::with_capacity(len);
let out = &mut values.spare_capacity_mut()[..len];
if source.map_checked_into(out, &mut apply) != Fail::default() {
let mut checked = |item: S::Item| {
let (value, failure) = apply(item);
(failure == Fail::default()).then_some(value)
};
match valid_bits {
None => source.try_map_into(out, &mut checked)?,
Some(valid_bits) => source.try_map_masked_into(valid_bits, out, &mut checked)?,
}
}
unsafe { values.set_len(len) };
Ok(values.freeze())
}