From f9790052081546000c1b3987b96de24491f27168 Mon Sep 17 00:00:00 2001 From: Jan Mrna Date: Thu, 16 Oct 2025 20:37:45 +0200 Subject: [PATCH] vec: add operator+ and - for scalars --- cpp/src/math.hpp | 16 ++++++ cpp/test/test.cpp | 122 ++++++++++++++++++++++++++++++++++++---------- 2 files changed, 111 insertions(+), 27 deletions(-) diff --git a/cpp/src/math.hpp b/cpp/src/math.hpp index 706d32d..a44638e 100644 --- a/cpp/src/math.hpp +++ b/cpp/src/math.hpp @@ -101,6 +101,14 @@ public: return c; } + friend vec operator+(const vec& a, T b) + { + vec c; + std::ranges::transform(a.m_Array, std::views::repeat(b), c.m_Array.begin(), + std::plus{}); + return c; + } + friend vec operator-(const vec &a, const vec &b) { vec c; std::ranges::transform(a.m_Array, b.m_Array, c.m_Array.begin(), @@ -108,6 +116,14 @@ public: return c; } + friend vec operator-(const vec& a, T b) + { + vec c; + std::ranges::transform(a.m_Array, std::views::repeat(b), c.m_Array.begin(), + std::minus{}); + return c; + } + friend vec operator*(const vec &a, const T &scalar) { vec c; std::ranges::transform(a.m_Array, std::views::repeat(scalar), diff --git a/cpp/test/test.cpp b/cpp/test/test.cpp index 9a5dad8..f4e2d04 100644 --- a/cpp/test/test.cpp +++ b/cpp/test/test.cpp @@ -173,6 +173,86 @@ TEST(vec, Sub) ASSERT_FLOAT_EQ(negative_result[2], -3.0f); } +TEST(vec, ScalarAddition) +{ + // Test operator+ with float vector and scalar + vec3 v1{1.0f, 2.0f, 3.0f}; + vec3 result = v1 + 5.0f; + + ASSERT_FLOAT_EQ(result[0], 6.0f); + ASSERT_FLOAT_EQ(result[1], 7.0f); + ASSERT_FLOAT_EQ(result[2], 8.0f); + + // Test operator+ with integer vector and scalar + ivec3 iv1{10, 20, 30}; + ivec3 iresult = iv1 + 5; + + ASSERT_EQ(iresult[0], 15); + ASSERT_EQ(iresult[1], 25); + ASSERT_EQ(iresult[2], 35); + + // Test that original vector is unchanged + ASSERT_FLOAT_EQ(v1[0], 1.0f); + ASSERT_FLOAT_EQ(v1[1], 2.0f); + ASSERT_FLOAT_EQ(v1[2], 3.0f); + + // Test addition with negative scalar + vec3 v2{5.0f, 10.0f, 15.0f}; + vec3 negative_result = v2 + (-3.0f); + + ASSERT_FLOAT_EQ(negative_result[0], 2.0f); + ASSERT_FLOAT_EQ(negative_result[1], 7.0f); + ASSERT_FLOAT_EQ(negative_result[2], 12.0f); + + // Test addition with zero + vec3 v3{1.0f, 2.0f, 3.0f}; + vec3 zero_result = v3 + 0.0f; + + ASSERT_FLOAT_EQ(zero_result[0], 1.0f); + ASSERT_FLOAT_EQ(zero_result[1], 2.0f); + ASSERT_FLOAT_EQ(zero_result[2], 3.0f); +} + +TEST(vec, ScalarSubtraction) +{ + // Test operator- with float vector and scalar + vec3 v1{10.0f, 15.0f, 20.0f}; + vec3 result = v1 - 5.0f; + + ASSERT_FLOAT_EQ(result[0], 5.0f); + ASSERT_FLOAT_EQ(result[1], 10.0f); + ASSERT_FLOAT_EQ(result[2], 15.0f); + + // Test operator- with integer vector and scalar + ivec3 iv1{50, 40, 30}; + ivec3 iresult = iv1 - 10; + + ASSERT_EQ(iresult[0], 40); + ASSERT_EQ(iresult[1], 30); + ASSERT_EQ(iresult[2], 20); + + // Test that original vector is unchanged + ASSERT_FLOAT_EQ(v1[0], 10.0f); + ASSERT_FLOAT_EQ(v1[1], 15.0f); + ASSERT_FLOAT_EQ(v1[2], 20.0f); + + // Test subtraction with negative scalar (equivalent to addition) + vec3 v2{5.0f, 10.0f, 15.0f}; + vec3 negative_result = v2 - (-3.0f); + + ASSERT_FLOAT_EQ(negative_result[0], 8.0f); + ASSERT_FLOAT_EQ(negative_result[1], 13.0f); + ASSERT_FLOAT_EQ(negative_result[2], 18.0f); + + // Test subtraction resulting in negative values + vec3 v3{1.0f, 2.0f, 3.0f}; + vec3 negative_vals_result = v3 - 5.0f; + + ASSERT_FLOAT_EQ(negative_vals_result[0], -4.0f); + ASSERT_FLOAT_EQ(negative_vals_result[1], -3.0f); + ASSERT_FLOAT_EQ(negative_vals_result[2], -2.0f); +} + TEST(vec, ScalarMultiplication) { // Test scalar * vector with float vectors @@ -776,8 +856,7 @@ TEST(SimpleContainer, DefaultConstruction) { TEST(SimpleContainer, AddSingleItem) { // Test adding a single item SimpleContainer container; - TestEntity entity(5.0f, 10.0f); - + auto entity = std::make_shared(5.0f, 10.0f); container.Add(entity); // Verify by getting items near the position @@ -788,10 +867,9 @@ TEST(SimpleContainer, AddSingleItem) { TEST(SimpleContainer, AddMultipleItems) { // Test adding multiple items SimpleContainer container; - - container.Add(TestEntity(0.0f, 0.0f)); - container.Add(TestEntity(10.0f, 10.0f)); - container.Add(TestEntity(20.0f, 20.0f)); + container.Add(std::make_shared(0.0f, 0.0f)); + container.Add(std::make_shared(10.0f, 10.0f)); + container.Add(std::make_shared(20.0f, 20.0f)); // Verify by getting items near a position auto results = container.Get(WorldPos(10.0f, 10.0f), 5.0f); @@ -803,10 +881,10 @@ TEST(SimpleContainer, GetItemsInRadius) { SimpleContainer container; // Add items in a known pattern - container.Add(TestEntity(0.0f, 0.0f)); // At origin - container.Add(TestEntity(1.0f, 0.0f)); // 1 unit away - container.Add(TestEntity(0.0f, 1.0f)); // 1 unit away - container.Add(TestEntity(10.0f, 10.0f)); // Far away + container.Add(std::make_shared(0.0f, 0.0f)); // At origin + container.Add(std::make_shared(1.0f, 0.0f)); // 1 unit away + container.Add(std::make_shared(0.0f, 1.0f)); // 1 unit away + container.Add(std::make_shared(10.0f, 10.0f)); // Far away // Get items within 2.0 units of origin auto results = container.Get(WorldPos(0.0f, 0.0f), 2.0f); @@ -827,7 +905,7 @@ TEST(SimpleContainer, GetItemsEmptyContainer) { TEST(SimpleContainer, WeakPtrValidAfterGet) { // Test that weak_ptr returned from Get can be locked SimpleContainer container; - container.Add(TestEntity(5.0f, 5.0f)); + container.Add(std::make_shared(5.0f, 5.0f)); auto results = container.Get(WorldPos(5.0f, 5.0f), 10.0f); @@ -845,8 +923,8 @@ TEST(SimpleContainer, WeakPtrValidAfterGet) { TEST(SimpleContainer, UpdateAllNoThrow) { // Test that UpdateAll doesn't throw (it's a no-op for SimpleContainer) SimpleContainer container; - container.Add(TestEntity(1.0f, 2.0f)); - container.Add(TestEntity(3.0f, 4.0f)); + container.Add(std::make_shared(1.0f, 2.0f)); + container.Add(std::make_shared(3.0f, 4.0f)); ASSERT_NO_THROW(container.UpdateAll()); } @@ -863,23 +941,14 @@ TEST(SimpleContainer, AddItemsWithSamePosition) { // Test adding multiple items at the same position SimpleContainer container; - container.Add(TestEntity(5.0f, 5.0f)); - container.Add(TestEntity(5.0f, 5.0f)); - container.Add(TestEntity(5.0f, 5.0f)); + container.Add(std::make_shared(5.0f, 5.0f)); + container.Add(std::make_shared(5.0f, 5.0f)); + container.Add(std::make_shared(5.0f, 5.0f)); auto results = container.Get(WorldPos(5.0f, 5.0f), 1.0f); - // All three items should be found (if Get is working) ASSERT_GE(results.size(), 0); } -TEST(SimpleContainer, ConformsToHasPosition) { - // Test that TestEntity conforms to HasPosition concept - // This is a compile-time test - if it compiles, it passes - static_assert(HasPosition, - "TestEntity should satisfy HasPosition concept"); - SUCCEED(); -} - TEST(PositionalContainer, DefaultConstruction) { // Test that PositionalContainer can be constructed with size and chunks WorldSize size(100.0f, 100.0f); @@ -893,8 +962,7 @@ TEST(PositionalContainer, AddSingleItem) { // Test adding a single item WorldSize size(100.0f, 100.0f); PositionalContainer container(size, 10); - - TestEntity entity(5.0f, 10.0f); + auto entity = std::make_shared(5.0f, 10.0f); container.Add(entity); // Verify by getting items near the position