ipa: libipa: vector: Generalize arithmetic operators

Instead of hand-coding all arithmetic operators, implement them based on
a generic apply() function that takes an operator-specific binary
operators. This will simplify adding missing arithmetic operators.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
This commit is contained in:
Laurent Pinchart 2024-11-16 21:02:52 +02:00
parent dd624b3fff
commit 49e961ca35

View file

@ -6,8 +6,10 @@
*/ */
#pragma once #pragma once
#include <algorithm>
#include <array> #include <array>
#include <cmath> #include <cmath>
#include <functional>
#include <optional> #include <optional>
#include <ostream> #include <ostream>
@ -66,36 +68,24 @@ public:
return ret; return ret;
} }
constexpr Vector<T, Rows> operator-(const Vector<T, Rows> &other) const constexpr Vector operator-(const Vector &other) const
{ {
Vector<T, Rows> ret; return apply(*this, other, std::minus<>{});
for (unsigned int i = 0; i < Rows; i++)
ret[i] = data_[i] - other[i];
return ret;
} }
constexpr Vector<T, Rows> operator+(const Vector<T, Rows> &other) const constexpr Vector operator+(const Vector &other) const
{ {
Vector<T, Rows> ret; return apply(*this, other, std::plus<>{});
for (unsigned int i = 0; i < Rows; i++)
ret[i] = data_[i] + other[i];
return ret;
} }
constexpr Vector<T, Rows> operator*(T factor) const constexpr Vector operator*(T factor) const
{ {
Vector<T, Rows> ret; return apply(*this, factor, std::multiplies<>{});
for (unsigned int i = 0; i < Rows; i++)
ret[i] = data_[i] * factor;
return ret;
} }
constexpr Vector<T, Rows> operator/(T factor) const constexpr Vector operator/(T factor) const
{ {
Vector<T, Rows> ret; return apply(*this, factor, std::divides<>{});
for (unsigned int i = 0; i < Rows; i++)
ret[i] = data_[i] / factor;
return ret;
} }
constexpr T dot(const Vector<T, Rows> &other) const constexpr T dot(const Vector<T, Rows> &other) const
@ -170,6 +160,28 @@ public:
} }
private: private:
template<class BinaryOp>
static constexpr Vector apply(const Vector &lhs, const Vector &rhs, BinaryOp op)
{
Vector result;
std::transform(lhs.data_.begin(), lhs.data_.end(),
rhs.data_.begin(), result.data_.begin(),
op);
return result;
}
template<class BinaryOp>
static constexpr Vector apply(const Vector &lhs, T rhs, BinaryOp op)
{
Vector result;
std::transform(lhs.data_.begin(), lhs.data_.end(),
result.data_.begin(),
[&op, rhs](T v) { return op(v, rhs); });
return result;
}
std::array<T, Rows> data_; std::array<T, Rows> data_;
}; };