From 6f7dbe752887e783e555cd6dcce79962b085b9ef Mon Sep 17 00:00:00 2001 From: Artem Zyktin Date: Tue, 2 Jun 2026 05:51:08 +0800 Subject: [PATCH] Add negative operator --- src/naive/naive_vec4.h | 5 ++++ src/tenvex/expressions/core.h | 12 ++++++++++ src/tenvex/expressions/dot3_impl.h | 2 +- src/tenvex/expressions/neg.h | 36 +++++++++++++++++++++++++++++ src/tenvex/expressions/neg_impl.hpp | 36 +++++++++++++++++++++++++++++ src/tenvex/expressions/vec4.h | 3 --- src/tenvex/tenvex.h | 1 + 7 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 src/tenvex/expressions/neg.h create mode 100644 src/tenvex/expressions/neg_impl.hpp diff --git a/src/naive/naive_vec4.h b/src/naive/naive_vec4.h index 910efd8..ae3ff46 100644 --- a/src/naive/naive_vec4.h +++ b/src/naive/naive_vec4.h @@ -89,4 +89,9 @@ inline bool approx_eq(vec4 a, vec4 b, float eps = 1e-6f) noexcept && std::fabs(a.w() - b.w()) <= eps; } +[[nodiscard]] inline vec4 operator-(vec4 v) noexcept +{ + return { -v.x(), -v.y(), -v.z(), -v.w() }; +} + } \ No newline at end of file diff --git a/src/tenvex/expressions/core.h b/src/tenvex/expressions/core.h index 50ef0d7..dee9a82 100644 --- a/src/tenvex/expressions/core.h +++ b/src/tenvex/expressions/core.h @@ -13,6 +13,12 @@ namespace tnvx::detail { +[[nodiscard]] TNVX_INLINE +float to_float(vf4 v) +{ + return _mm_cvtss_f32(v); +} + [[nodiscard]] TNVX_INLINE bool eq(vf4 a, vf4 b) { @@ -39,6 +45,12 @@ float get_lane(vf4 v) noexcept return _mm_cvtss_f32(_mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, lane))); } +[[nodiscard]] TNVX_INLINE +vf4 neg(vf4 v) noexcept +{ + return _mm_xor_ps(v, _mm_set1_ps(-0.0f)); +} + [[nodiscard]] TNVX_INLINE vf4 add(vf4 l, vf4 r) noexcept { diff --git a/src/tenvex/expressions/dot3_impl.h b/src/tenvex/expressions/dot3_impl.h index 03cadd6..3c3f864 100644 --- a/src/tenvex/expressions/dot3_impl.h +++ b/src/tenvex/expressions/dot3_impl.h @@ -24,7 +24,7 @@ template TNVX_INLINE Dot3::operator float() const noexcept { - return _mm_cvtss_f32(eval()); + return detail::to_float(eval()); } template diff --git a/src/tenvex/expressions/neg.h b/src/tenvex/expressions/neg.h new file mode 100644 index 0000000..4056851 --- /dev/null +++ b/src/tenvex/expressions/neg.h @@ -0,0 +1,36 @@ +#pragma once + +#include "core.h" +#include "expression.h" +#include "traits.h" +#include "concepts.h" + +namespace tnvx +{ + +template +struct Neg : Expr> +{ + TNVX_INLINE + explicit Neg(const E& TNVX_RESTRICT e) noexcept; + + [[nodiscard]] TNVX_INLINE + vf4 eval() const noexcept; + + [[nodiscard]] TNVX_INLINE + operator float() const noexcept requires scalar_expr; + +private: + tnvx_ref_or_value_t _e; +}; + +template inline constexpr bool is_vec_expr> = true; +template inline constexpr bool is_scalar_expr> = true; + +template +[[nodiscard]] TNVX_INLINE +Neg operator-(const E& e) noexcept; + +} + +#include "neg_impl.hpp" diff --git a/src/tenvex/expressions/neg_impl.hpp b/src/tenvex/expressions/neg_impl.hpp new file mode 100644 index 0000000..ecf30f1 --- /dev/null +++ b/src/tenvex/expressions/neg_impl.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include "neg.h" + +namespace tnvx +{ + +template +TNVX_INLINE +tnvx::Neg::Neg(const E& TNVX_RESTRICT e) noexcept + : _e(e) +{ +} + +template +TNVX_INLINE +vf4 Neg::eval() const noexcept +{ + return detail::neg(_e.eval()); +} + +template +TNVX_INLINE +Neg::operator float() const noexcept requires scalar_expr +{ + return detail::to_float(eval()); +} + +template +TNVX_INLINE +Neg operator-(const E& e) noexcept +{ + return Neg(e); +} + +} diff --git a/src/tenvex/expressions/vec4.h b/src/tenvex/expressions/vec4.h index 82960ec..30be4e7 100644 --- a/src/tenvex/expressions/vec4.h +++ b/src/tenvex/expressions/vec4.h @@ -35,9 +35,6 @@ struct alignas(16) vec4 : Expr [[nodiscard]] TNVX_INLINE vf4 eval() const noexcept; - [[nodiscard]] TNVX_INLINE - vec4 operator-() const noexcept; - private: vf4 _data; diff --git a/src/tenvex/tenvex.h b/src/tenvex/tenvex.h index f87fc6b..ad2e4ba 100644 --- a/src/tenvex/tenvex.h +++ b/src/tenvex/tenvex.h @@ -1,5 +1,6 @@ #pragma once +#include "expressions/neg.h" #include "expressions/add.h" #include "expressions/sub.h" #include "expressions/scalar.h"