in cpp/src/arrow/compute/kernels/scalar_arithmetic.cc [1415:1904]
void RegisterScalarArithmetic(FunctionRegistry* registry) {
// NOTE for registration of arithmetic kernels: to minimize code generation,
// it is advised to template the actual executors with physical execution
// types (e.g. Int64 instead of Duration or Timestamp).
// ----------------------------------------------------------------------
auto absolute_value =
MakeUnaryArithmeticFunction<AbsoluteValue>("abs", absolute_value_doc);
AddDecimalUnaryKernels<AbsoluteValue>(absolute_value.get());
// abs(duration)
for (auto unit : TimeUnit::values()) {
auto exec = ArithmeticExecFromOp<ScalarUnary, AbsoluteValue>(duration(unit));
DCHECK_OK(
absolute_value->AddKernel({duration(unit)}, OutputType(duration(unit)), exec));
}
DCHECK_OK(registry->AddFunction(std::move(absolute_value)));
// ----------------------------------------------------------------------
auto absolute_value_checked = MakeUnaryArithmeticFunctionNotNull<AbsoluteValueChecked>(
"abs_checked", absolute_value_checked_doc);
AddDecimalUnaryKernels<AbsoluteValueChecked>(absolute_value_checked.get());
// abs_checked(duraton)
for (auto unit : TimeUnit::values()) {
auto exec =
ArithmeticExecFromOp<ScalarUnaryNotNull, AbsoluteValueChecked>(duration(unit));
DCHECK_OK(absolute_value_checked->AddKernel({duration(unit)},
OutputType(duration(unit)), exec));
}
DCHECK_OK(registry->AddFunction(std::move(absolute_value_checked)));
// ----------------------------------------------------------------------
auto add = MakeArithmeticFunction<Add>("add", add_doc);
AddDecimalBinaryKernels<Add>("add", add.get());
// Add add(timestamp, duration) -> timestamp
for (auto unit : TimeUnit::values()) {
InputType in_type(match::TimestampTypeUnit(unit));
auto exec = ScalarBinary<Int64Type, Int64Type, Int64Type, Add>::Exec;
DCHECK_OK(add->AddKernel({in_type, duration(unit)}, OutputType(FirstType), exec));
DCHECK_OK(add->AddKernel({duration(unit), in_type}, OutputType(LastType), exec));
}
// Add add(duration, duration) -> duration
for (auto unit : TimeUnit::values()) {
InputType in_type(match::DurationTypeUnit(unit));
auto exec = ArithmeticExecFromOp<ScalarBinaryEqualTypes, Add>(Type::DURATION);
DCHECK_OK(add->AddKernel({in_type, in_type}, duration(unit), std::move(exec)));
}
AddArithmeticFunctionTimeDuration<AddTimeDuration>(add);
AddArithmeticFunctionDurationTime<AddTimeDuration>(add);
DCHECK_OK(registry->AddFunction(std::move(add)));
// ----------------------------------------------------------------------
auto add_checked =
MakeArithmeticFunctionNotNull<AddChecked>("add_checked", add_checked_doc);
AddDecimalBinaryKernels<AddChecked>("add_checked", add_checked.get());
// Add add_checked(timestamp, duration) -> timestamp
for (auto unit : TimeUnit::values()) {
InputType in_type(match::TimestampTypeUnit(unit));
auto exec = ScalarBinary<Int64Type, Int64Type, Int64Type, AddChecked>::Exec;
DCHECK_OK(
add_checked->AddKernel({in_type, duration(unit)}, OutputType(FirstType), exec));
DCHECK_OK(
add_checked->AddKernel({duration(unit), in_type}, OutputType(LastType), exec));
}
// Add add(duration, duration) -> duration
for (auto unit : TimeUnit::values()) {
InputType in_type(match::DurationTypeUnit(unit));
auto exec = ArithmeticExecFromOp<ScalarBinaryEqualTypes, AddChecked>(Type::DURATION);
DCHECK_OK(
add_checked->AddKernel({in_type, in_type}, duration(unit), std::move(exec)));
}
AddArithmeticFunctionTimeDuration<AddTimeDurationChecked>(add_checked);
AddArithmeticFunctionDurationTime<AddTimeDurationChecked>(add_checked);
DCHECK_OK(registry->AddFunction(std::move(add_checked)));
// ----------------------------------------------------------------------
auto subtract = MakeArithmeticFunction<Subtract>("subtract", sub_doc);
AddDecimalBinaryKernels<Subtract>("subtract", subtract.get());
// Add subtract(timestamp, timestamp) -> duration
for (auto unit : TimeUnit::values()) {
InputType in_type(match::TimestampTypeUnit(unit));
auto exec = ArithmeticExecFromOp<ScalarBinaryEqualTypes, Subtract>(Type::TIMESTAMP);
DCHECK_OK(subtract->AddKernel({in_type, in_type},
OutputType::Resolver(ResolveTemporalOutput),
std::move(exec)));
}
// Add subtract(timestamp, duration) -> timestamp
for (auto unit : TimeUnit::values()) {
InputType in_type(match::TimestampTypeUnit(unit));
auto exec = ScalarBinary<Int64Type, Int64Type, Int64Type, Subtract>::Exec;
DCHECK_OK(subtract->AddKernel({in_type, duration(unit)}, OutputType(FirstType),
std::move(exec)));
}
// Add subtract(duration, duration) -> duration
for (auto unit : TimeUnit::values()) {
InputType in_type(match::DurationTypeUnit(unit));
auto exec = ArithmeticExecFromOp<ScalarBinaryEqualTypes, Subtract>(Type::DURATION);
DCHECK_OK(subtract->AddKernel({in_type, in_type}, duration(unit), std::move(exec)));
}
// Add subtract(time32, time32) -> duration
for (auto unit : {TimeUnit::SECOND, TimeUnit::MILLI}) {
InputType in_type(match::Time32TypeUnit(unit));
auto exec = ScalarBinaryEqualTypes<Int64Type, Int32Type, Subtract>::Exec;
DCHECK_OK(subtract->AddKernel({in_type, in_type}, duration(unit), std::move(exec)));
}
// Add subtract(time64, time64) -> duration
for (auto unit : {TimeUnit::MICRO, TimeUnit::NANO}) {
InputType in_type(match::Time64TypeUnit(unit));
auto exec = ScalarBinaryEqualTypes<Int64Type, Int64Type, Subtract>::Exec;
DCHECK_OK(subtract->AddKernel({in_type, in_type}, duration(unit), std::move(exec)));
}
// Add subtract(date32, date32) -> duration(TimeUnit::SECOND)
InputType in_type_date_32(date32());
auto exec_date_32 = ScalarBinaryEqualTypes<Int64Type, Int32Type, SubtractDate32>::Exec;
DCHECK_OK(subtract->AddKernel({in_type_date_32, in_type_date_32},
duration(TimeUnit::SECOND), std::move(exec_date_32)));
// Add subtract(date64, date64) -> duration(TimeUnit::MILLI)
InputType in_type_date_64(date64());
auto exec_date_64 = ScalarBinaryEqualTypes<Int64Type, Int64Type, Subtract>::Exec;
DCHECK_OK(subtract->AddKernel({in_type_date_64, in_type_date_64},
duration(TimeUnit::MILLI), std::move(exec_date_64)));
AddArithmeticFunctionTimeDuration<SubtractTimeDuration>(subtract);
DCHECK_OK(registry->AddFunction(std::move(subtract)));
// ----------------------------------------------------------------------
auto subtract_checked =
MakeArithmeticFunctionNotNull<SubtractChecked>("subtract_checked", sub_checked_doc);
AddDecimalBinaryKernels<SubtractChecked>("subtract_checked", subtract_checked.get());
// Add subtract_checked(timestamp, timestamp) -> duration
for (auto unit : TimeUnit::values()) {
InputType in_type(match::TimestampTypeUnit(unit));
auto exec =
ArithmeticExecFromOp<ScalarBinaryEqualTypes, SubtractChecked>(Type::TIMESTAMP);
DCHECK_OK(subtract_checked->AddKernel({in_type, in_type},
OutputType::Resolver(ResolveTemporalOutput),
std::move(exec)));
}
// Add subtract_checked(timestamp, duration) -> timestamp
for (auto unit : TimeUnit::values()) {
InputType in_type(match::TimestampTypeUnit(unit));
auto exec = ScalarBinary<Int64Type, Int64Type, Int64Type, SubtractChecked>::Exec;
DCHECK_OK(subtract_checked->AddKernel({in_type, duration(unit)},
OutputType(FirstType), std::move(exec)));
}
// Add subtract_checked(duration, duration) -> duration
for (auto unit : TimeUnit::values()) {
InputType in_type(match::DurationTypeUnit(unit));
auto exec =
ArithmeticExecFromOp<ScalarBinaryEqualTypes, SubtractChecked>(Type::DURATION);
DCHECK_OK(
subtract_checked->AddKernel({in_type, in_type}, duration(unit), std::move(exec)));
}
// Add subtract_checked(date32, date32) -> duration(TimeUnit::SECOND)
auto exec_date_32_checked =
ScalarBinaryEqualTypes<Int64Type, Int32Type, SubtractCheckedDate32>::Exec;
DCHECK_OK(subtract_checked->AddKernel({in_type_date_32, in_type_date_32},
duration(TimeUnit::SECOND),
std::move(exec_date_32_checked)));
// Add subtract_checked(date64, date64) -> duration(TimeUnit::MILLI)
auto exec_date_64_checked =
ScalarBinaryEqualTypes<Int64Type, Int64Type, SubtractChecked>::Exec;
DCHECK_OK(subtract_checked->AddKernel({in_type_date_64, in_type_date_64},
duration(TimeUnit::MILLI),
std::move(exec_date_64_checked)));
// Add subtract_checked(time32, time32) -> duration
for (auto unit : {TimeUnit::SECOND, TimeUnit::MILLI}) {
InputType in_type(match::Time32TypeUnit(unit));
auto exec = ScalarBinaryEqualTypes<Int64Type, Int32Type, SubtractChecked>::Exec;
DCHECK_OK(
subtract_checked->AddKernel({in_type, in_type}, duration(unit), std::move(exec)));
}
// Add subtract_checked(time64, time64) -> duration
for (auto unit : {TimeUnit::MICRO, TimeUnit::NANO}) {
InputType in_type(match::Time64TypeUnit(unit));
auto exec = ScalarBinaryEqualTypes<Int64Type, Int64Type, SubtractChecked>::Exec;
DCHECK_OK(
subtract_checked->AddKernel({in_type, in_type}, duration(unit), std::move(exec)));
}
AddArithmeticFunctionTimeDuration<SubtractTimeDurationChecked>(subtract_checked);
DCHECK_OK(registry->AddFunction(std::move(subtract_checked)));
// ----------------------------------------------------------------------
auto multiply = MakeArithmeticFunction<Multiply>("multiply", mul_doc);
AddDecimalBinaryKernels<Multiply>("multiply", multiply.get());
// Add multiply(duration, int64) -> duration
for (auto unit : TimeUnit::values()) {
auto exec = ArithmeticExecFromOp<ScalarBinaryEqualTypes, Multiply>(Type::DURATION);
DCHECK_OK(multiply->AddKernel({duration(unit), int64()}, duration(unit), exec));
DCHECK_OK(multiply->AddKernel({int64(), duration(unit)}, duration(unit), exec));
}
DCHECK_OK(registry->AddFunction(std::move(multiply)));
// ----------------------------------------------------------------------
auto multiply_checked =
MakeArithmeticFunctionNotNull<MultiplyChecked>("multiply_checked", mul_checked_doc);
AddDecimalBinaryKernels<MultiplyChecked>("multiply_checked", multiply_checked.get());
// Add multiply_checked(duration, int64) -> duration
for (auto unit : TimeUnit::values()) {
auto exec =
ArithmeticExecFromOp<ScalarBinaryEqualTypes, MultiplyChecked>(Type::DURATION);
DCHECK_OK(
multiply_checked->AddKernel({duration(unit), int64()}, duration(unit), exec));
DCHECK_OK(
multiply_checked->AddKernel({int64(), duration(unit)}, duration(unit), exec));
}
DCHECK_OK(registry->AddFunction(std::move(multiply_checked)));
// ----------------------------------------------------------------------
auto divide = MakeArithmeticFunctionNotNull<Divide>("divide", div_doc);
AddDecimalBinaryKernels<Divide>("divide", divide.get());
// Add divide(duration, int64) -> duration
for (auto unit : TimeUnit::values()) {
auto exec = ScalarBinaryNotNull<Int64Type, Int64Type, Int64Type, Divide>::Exec;
DCHECK_OK(
divide->AddKernel({duration(unit), int64()}, duration(unit), std::move(exec)));
}
// Add divide(duration, duration) -> float64
for (auto unit : TimeUnit::values()) {
auto exec =
ScalarBinaryNotNull<DoubleType, Int64Type, Int64Type, FloatingDivide>::Exec;
DCHECK_OK(
divide->AddKernel({duration(unit), duration(unit)}, float64(), std::move(exec)));
}
DCHECK_OK(registry->AddFunction(std::move(divide)));
// ----------------------------------------------------------------------
auto divide_checked =
MakeArithmeticFunctionNotNull<DivideChecked>("divide_checked", div_checked_doc);
AddDecimalBinaryKernels<DivideChecked>("divide_checked", divide_checked.get());
// Add divide_checked(duration, int64) -> duration
for (auto unit : TimeUnit::values()) {
auto exec = ScalarBinaryNotNull<Int64Type, Int64Type, Int64Type, DivideChecked>::Exec;
DCHECK_OK(divide_checked->AddKernel({duration(unit), int64()}, duration(unit),
std::move(exec)));
}
// Add divide_checked(duration, duration) -> float64
for (auto unit : TimeUnit::values()) {
auto exec = ScalarBinaryNotNull<DoubleType, Int64Type, Int64Type,
FloatingDivideChecked>::Exec;
DCHECK_OK(divide_checked->AddKernel({duration(unit), duration(unit)}, float64(),
std::move(exec)));
}
DCHECK_OK(registry->AddFunction(std::move(divide_checked)));
// ----------------------------------------------------------------------
auto negate = MakeUnaryArithmeticFunction<Negate>("negate", negate_doc);
AddDecimalUnaryKernels<Negate>(negate.get());
// Add neg(duration) -> duration
for (auto unit : TimeUnit::values()) {
auto exec = ArithmeticExecFromOp<ScalarUnary, Negate>(duration(unit));
DCHECK_OK(negate->AddKernel({duration(unit)}, OutputType(duration(unit)), exec));
}
DCHECK_OK(registry->AddFunction(std::move(negate)));
// ----------------------------------------------------------------------
auto negate_checked = MakeUnarySignedArithmeticFunctionNotNull<NegateChecked>(
"negate_checked", negate_checked_doc);
AddDecimalUnaryKernels<NegateChecked>(negate_checked.get());
// Add neg_checked(duration) -> duration
for (auto unit : TimeUnit::values()) {
auto exec = ArithmeticExecFromOp<ScalarUnaryNotNull, Negate>(duration(unit));
DCHECK_OK(
negate_checked->AddKernel({duration(unit)}, OutputType(duration(unit)), exec));
}
DCHECK_OK(registry->AddFunction(std::move(negate_checked)));
// ----------------------------------------------------------------------
auto power = MakeArithmeticFunction<Power, ArithmeticDecimalToFloatingPointFunction>(
"power", pow_doc);
DCHECK_OK(registry->AddFunction(std::move(power)));
// ----------------------------------------------------------------------
auto power_checked =
MakeArithmeticFunctionNotNull<PowerChecked,
ArithmeticDecimalToFloatingPointFunction>(
"power_checked", pow_checked_doc);
DCHECK_OK(registry->AddFunction(std::move(power_checked)));
// ----------------------------------------------------------------------
auto exp = MakeUnaryArithmeticFunctionFloatingPoint<Exp>("exp", exp_doc);
DCHECK_OK(registry->AddFunction(std::move(exp)));
// ----------------------------------------------------------------------
auto expm1 = MakeUnaryArithmeticFunctionFloatingPoint<Expm1>("expm1", expm1_doc);
DCHECK_OK(registry->AddFunction(std::move(expm1)));
// ----------------------------------------------------------------------
auto sqrt = MakeUnaryArithmeticFunctionFloatingPoint<SquareRoot>("sqrt", sqrt_doc);
DCHECK_OK(registry->AddFunction(std::move(sqrt)));
// ----------------------------------------------------------------------
auto sqrt_checked = MakeUnaryArithmeticFunctionFloatingPointNotNull<SquareRootChecked>(
"sqrt_checked", sqrt_checked_doc);
DCHECK_OK(registry->AddFunction(std::move(sqrt_checked)));
// ----------------------------------------------------------------------
auto sign =
MakeUnaryArithmeticFunctionWithFixedIntOutType<Sign, Int8Type>("sign", sign_doc);
// sign(duration)
for (auto unit : TimeUnit::values()) {
auto exec = ScalarUnary<Int8Type, Int64Type, Sign>::Exec;
DCHECK_OK(sign->AddKernel({duration(unit)}, int8(), std::move(exec)));
}
DCHECK_OK(registry->AddFunction(std::move(sign)));
// ----------------------------------------------------------------------
// Bitwise functions
{
auto bit_wise_not = std::make_shared<ArithmeticFunction>(
"bit_wise_not", Arity::Unary(), bit_wise_not_doc);
for (const auto& ty : IntTypes()) {
auto exec = TypeAgnosticBitWiseExecFromOp<ScalarUnaryNotNull, BitWiseNot>(ty);
DCHECK_OK(bit_wise_not->AddKernel({ty}, ty, exec));
}
AddNullExec(bit_wise_not.get());
DCHECK_OK(registry->AddFunction(std::move(bit_wise_not)));
}
auto bit_wise_and =
MakeBitWiseFunctionNotNull<BitWiseAnd>("bit_wise_and", bit_wise_and_doc);
DCHECK_OK(registry->AddFunction(std::move(bit_wise_and)));
auto bit_wise_or =
MakeBitWiseFunctionNotNull<BitWiseOr>("bit_wise_or", bit_wise_or_doc);
DCHECK_OK(registry->AddFunction(std::move(bit_wise_or)));
auto bit_wise_xor =
MakeBitWiseFunctionNotNull<BitWiseXor>("bit_wise_xor", bit_wise_xor_doc);
DCHECK_OK(registry->AddFunction(std::move(bit_wise_xor)));
auto shift_left = MakeShiftFunctionNotNull<ShiftLeft>("shift_left", shift_left_doc);
DCHECK_OK(registry->AddFunction(std::move(shift_left)));
auto shift_left_checked = MakeShiftFunctionNotNull<ShiftLeftChecked>(
"shift_left_checked", shift_left_checked_doc);
DCHECK_OK(registry->AddFunction(std::move(shift_left_checked)));
auto shift_right = MakeShiftFunctionNotNull<ShiftRight>("shift_right", shift_right_doc);
DCHECK_OK(registry->AddFunction(std::move(shift_right)));
auto shift_right_checked = MakeShiftFunctionNotNull<ShiftRightChecked>(
"shift_right_checked", shift_right_checked_doc);
DCHECK_OK(registry->AddFunction(std::move(shift_right_checked)));
// ----------------------------------------------------------------------
// Trig functions
auto sin = MakeUnaryArithmeticFunctionFloatingPoint<Sin>("sin", sin_doc);
DCHECK_OK(registry->AddFunction(std::move(sin)));
auto sin_checked = MakeUnaryArithmeticFunctionFloatingPointNotNull<SinChecked>(
"sin_checked", sin_checked_doc);
DCHECK_OK(registry->AddFunction(std::move(sin_checked)));
auto sinh = MakeUnaryArithmeticFunctionFloatingPoint<Sinh>("sinh", sinh_doc);
DCHECK_OK(registry->AddFunction(std::move(sinh)));
auto cos = MakeUnaryArithmeticFunctionFloatingPoint<Cos>("cos", cos_doc);
DCHECK_OK(registry->AddFunction(std::move(cos)));
auto cos_checked = MakeUnaryArithmeticFunctionFloatingPointNotNull<CosChecked>(
"cos_checked", cos_checked_doc);
DCHECK_OK(registry->AddFunction(std::move(cos_checked)));
auto cosh = MakeUnaryArithmeticFunctionFloatingPoint<Cosh>("cosh", cosh_doc);
DCHECK_OK(registry->AddFunction(std::move(cosh)));
auto tan = MakeUnaryArithmeticFunctionFloatingPoint<Tan>("tan", tan_doc);
DCHECK_OK(registry->AddFunction(std::move(tan)));
auto tan_checked = MakeUnaryArithmeticFunctionFloatingPointNotNull<TanChecked>(
"tan_checked", tan_checked_doc);
DCHECK_OK(registry->AddFunction(std::move(tan_checked)));
auto tanh = MakeUnaryArithmeticFunctionFloatingPoint<Tanh>("tanh", tanh_doc);
DCHECK_OK(registry->AddFunction(std::move(tanh)));
auto asin = MakeUnaryArithmeticFunctionFloatingPoint<Asin>("asin", asin_doc);
DCHECK_OK(registry->AddFunction(std::move(asin)));
auto asin_checked = MakeUnaryArithmeticFunctionFloatingPointNotNull<AsinChecked>(
"asin_checked", asin_checked_doc);
DCHECK_OK(registry->AddFunction(std::move(asin_checked)));
auto asinh = MakeUnaryArithmeticFunctionFloatingPoint<Asinh>("asinh", asinh_doc);
DCHECK_OK(registry->AddFunction(std::move(asinh)));
auto acos = MakeUnaryArithmeticFunctionFloatingPoint<Acos>("acos", acos_doc);
DCHECK_OK(registry->AddFunction(std::move(acos)));
auto acos_checked = MakeUnaryArithmeticFunctionFloatingPointNotNull<AcosChecked>(
"acos_checked", acos_checked_doc);
DCHECK_OK(registry->AddFunction(std::move(acos_checked)));
auto acosh = MakeUnaryArithmeticFunctionFloatingPoint<Acosh>("acosh", acosh_doc);
DCHECK_OK(registry->AddFunction(std::move(acosh)));
auto acosh_checked = MakeUnaryArithmeticFunctionFloatingPointNotNull<AcoshChecked>(
"acosh_checked", acosh_checked_doc);
DCHECK_OK(registry->AddFunction(std::move(acosh_checked)));
auto atan = MakeUnaryArithmeticFunctionFloatingPoint<Atan>("atan", atan_doc);
DCHECK_OK(registry->AddFunction(std::move(atan)));
auto atan2 = MakeArithmeticFunctionFloatingPoint<Atan2>("atan2", atan2_doc);
DCHECK_OK(registry->AddFunction(std::move(atan2)));
auto atanh = MakeUnaryArithmeticFunctionFloatingPoint<Atanh>("atanh", atanh_doc);
DCHECK_OK(registry->AddFunction(std::move(atanh)));
auto atanh_checked = MakeUnaryArithmeticFunctionFloatingPointNotNull<AtanhChecked>(
"atanh_checked", atanh_checked_doc);
DCHECK_OK(registry->AddFunction(std::move(atanh_checked)));
// ----------------------------------------------------------------------
// Logarithms
auto ln = MakeUnaryArithmeticFunctionFloatingPoint<LogNatural>("ln", ln_doc);
DCHECK_OK(registry->AddFunction(std::move(ln)));
auto ln_checked = MakeUnaryArithmeticFunctionFloatingPointNotNull<LogNaturalChecked>(
"ln_checked", ln_checked_doc);
DCHECK_OK(registry->AddFunction(std::move(ln_checked)));
auto log10 = MakeUnaryArithmeticFunctionFloatingPoint<Log10>("log10", log10_doc);
DCHECK_OK(registry->AddFunction(std::move(log10)));
auto log10_checked = MakeUnaryArithmeticFunctionFloatingPointNotNull<Log10Checked>(
"log10_checked", log10_checked_doc);
DCHECK_OK(registry->AddFunction(std::move(log10_checked)));
auto log2 = MakeUnaryArithmeticFunctionFloatingPoint<Log2>("log2", log2_doc);
DCHECK_OK(registry->AddFunction(std::move(log2)));
auto log2_checked = MakeUnaryArithmeticFunctionFloatingPointNotNull<Log2Checked>(
"log2_checked", log2_checked_doc);
DCHECK_OK(registry->AddFunction(std::move(log2_checked)));
auto log1p = MakeUnaryArithmeticFunctionFloatingPoint<Log1p>("log1p", log1p_doc);
DCHECK_OK(registry->AddFunction(std::move(log1p)));
auto log1p_checked = MakeUnaryArithmeticFunctionFloatingPointNotNull<Log1pChecked>(
"log1p_checked", log1p_checked_doc);
DCHECK_OK(registry->AddFunction(std::move(log1p_checked)));
auto logb = MakeArithmeticFunctionFloatingPoint<Logb>("logb", logb_doc);
DCHECK_OK(registry->AddFunction(std::move(logb)));
auto logb_checked = MakeArithmeticFunctionFloatingPointNotNull<LogbChecked>(
"logb_checked", logb_checked_doc);
DCHECK_OK(registry->AddFunction(std::move(logb_checked)));
}