1#ifndef TATAMI_ARITHMETIC_UTILS_HPP
2#define TATAMI_ARITHMETIC_UTILS_HPP
38template<ArithmeticOperation op_,
bool right_,
typename Value_,
typename Scalar_>
39auto delayed_arithmetic(Value_ val, Scalar_ scalar) {
41 if constexpr(right_) {
49 if constexpr(right_) {
56 if constexpr(op_ == ArithmeticOperation::ADD) {
59 }
else if constexpr(op_ == ArithmeticOperation::MULTIPLY) {
62 }
else if constexpr(op_ == ArithmeticOperation::SUBTRACT) {
65 }
else if constexpr(op_ == ArithmeticOperation::DIVIDE) {
73 }
else if constexpr(op_ == ArithmeticOperation::POWER) {
74 return std::pow(left, right);
76 }
else if constexpr(op_ == ArithmeticOperation::MODULO) {
79 auto quo = left / right;
80 if constexpr(std::numeric_limits<
decltype(quo)>::is_integer) {
81 auto rem = left % right;
82 return rem + (quo < 0 && rem != 0 ? right : 0);
84 auto rem = std::fmod(left, right);
85 return rem + (quo < 0 && rem != 0 ? right : 0);
88 }
else if constexpr(op_ == ArithmeticOperation::INTEGER_DIVIDE) {
89 auto out = left / right;
90 if constexpr(std::numeric_limits<
decltype(out)>::is_integer) {
93 return out - (out < 0 ? (left % right != 0) : 0);
95 return std::floor(out);
105template<ArithmeticOperation op_,
bool right_,
typename Value_,
typename Scalar_>
106constexpr bool has_unsafe_divide_by_zero() {
107 typedef decltype(delayed_arithmetic<op_, right_>(std::declval<Value_>(), std::declval<Scalar_>())) Product;
108 if constexpr(std::numeric_limits<Product>::is_iec559) {
116 if constexpr(op_ == ArithmeticOperation::DIVIDE) {
119 if constexpr(op_ == ArithmeticOperation::MODULO) {
122 if constexpr(op_ == ArithmeticOperation::INTEGER_DIVIDE) {
Flexible representations for matrix data.
Definition Extractor.hpp:15
ArithmeticOperation
Definition arithmetic_utils.hpp:23