use crate::Result;
use crate::arena::{DataValue, bvec};
use crate::operators::eager::Cx;
use crate::operators::extract::{RestArgs, StrictNum};
use datavalue::NumberValue;
#[derive(Clone, Copy)]
pub(crate) enum UnaryMathOp {
Abs,
Ceil,
Floor,
}
impl UnaryMathOp {
#[inline]
fn apply(self, x: f64) -> f64 {
match self {
UnaryMathOp::Abs => x.abs(),
UnaryMathOp::Ceil => x.ceil(),
UnaryMathOp::Floor => x.floor(),
}
}
}
#[inline(always)]
pub(crate) fn unary_math<'a>(
cx: &mut Cx<'_, 'a>,
first: f64,
rest: RestArgs<'a, StrictNum>,
op: UnaryMathOp,
) -> Result<&'a DataValue<'a>> {
let to_number = NumberValue::from_f64;
if rest.is_empty() {
return Ok(cx.alloc(DataValue::Number(to_number(op.apply(first)))));
}
let mut items = bvec::<DataValue<'a>>(cx.arena, rest.len() + 1);
items.push(DataValue::Number(to_number(op.apply(first))));
for i in 0..rest.len() {
let n = rest.get(i, cx)?;
items.push(DataValue::Number(to_number(op.apply(n))));
}
Ok(cx.alloc(DataValue::Array(items.into_bump_slice())))
}