[v4,06/17] ipa: libipa: vector: Generalize arithmetic operators
diff mbox series

Message ID 20241119121928.30939-7-laurent.pinchart@ideasonboard.com
State Accepted
Headers show
Series
  • Improve linear algebra helpers in libipa
Related show

Commit Message

Laurent Pinchart Nov. 19, 2024, 12:19 p.m. UTC
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>
---
Changes since v3:

- Replace std::function with a templated argument

Changes since v2:

- Include <algorithm>
- Use std::plus, std::minus, std::multiplies and std::divides
---
 src/ipa/libipa/vector.h | 52 +++++++++++++++++++++++++----------------
 1 file changed, 32 insertions(+), 20 deletions(-)

Patch
diff mbox series

diff --git a/src/ipa/libipa/vector.h b/src/ipa/libipa/vector.h
index b4eb19707063..10e16d41aa8b 100644
--- a/src/ipa/libipa/vector.h
+++ b/src/ipa/libipa/vector.h
@@ -6,8 +6,10 @@ 
  */
 #pragma once
 
+#include <algorithm>
 #include <array>
 #include <cmath>
+#include <functional>
 #include <optional>
 #include <ostream>
 
@@ -70,36 +72,24 @@  public:
 		return ret;
 	}
 
-	constexpr Vector<T, Rows> operator-(const Vector<T, Rows> &other) const
+	constexpr Vector operator-(const Vector &other) const
 	{
-		Vector<T, Rows> ret;
-		for (unsigned int i = 0; i < Rows; i++)
-			ret[i] = data_[i] - other[i];
-		return ret;
+		return apply(*this, other, std::minus<>{});
 	}
 
-	constexpr Vector<T, Rows> operator+(const Vector<T, Rows> &other) const
+	constexpr Vector operator+(const Vector &other) const
 	{
-		Vector<T, Rows> ret;
-		for (unsigned int i = 0; i < Rows; i++)
-			ret[i] = data_[i] + other[i];
-		return ret;
+		return apply(*this, other, std::plus<>{});
 	}
 
-	constexpr Vector<T, Rows> operator*(T factor) const
+	constexpr Vector operator*(T factor) const
 	{
-		Vector<T, Rows> ret;
-		for (unsigned int i = 0; i < Rows; i++)
-			ret[i] = data_[i] * factor;
-		return ret;
+		return apply(*this, factor, std::multiplies<>{});
 	}
 
-	constexpr Vector<T, Rows> operator/(T factor) const
+	constexpr Vector operator/(T factor) const
 	{
-		Vector<T, Rows> ret;
-		for (unsigned int i = 0; i < Rows; i++)
-			ret[i] = data_[i] / factor;
-		return ret;
+		return apply(*this, factor, std::divides<>{});
 	}
 
 	constexpr T dot(const Vector<T, Rows> &other) const
@@ -174,6 +164,28 @@  public:
 	}
 
 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_;
 };