mirror of
https://github.com/orange-cpp/omath.git
synced 2026-04-26 07:03:27 +00:00
added typecasting for vectors
This commit is contained in:
@@ -26,6 +26,12 @@ namespace omath
|
|||||||
// Constructors
|
// Constructors
|
||||||
constexpr Vector2() = default;
|
constexpr Vector2() = default;
|
||||||
|
|
||||||
|
template<class CastedType>
|
||||||
|
requires std::is_arithmetic_v<CastedType>
|
||||||
|
[[nodiscard]] constexpr explicit operator Vector2<CastedType>() const noexcept
|
||||||
|
{
|
||||||
|
return {static_cast<CastedType>(x), static_cast<CastedType>(y)};
|
||||||
|
}
|
||||||
constexpr Vector2(const Type& x, const Type& y) noexcept: x(x), y(y)
|
constexpr Vector2(const Type& x, const Type& y) noexcept: x(x), y(y)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,13 @@ namespace omath
|
|||||||
}
|
}
|
||||||
constexpr Vector3() noexcept: Vector2<Type>() {};
|
constexpr Vector3() noexcept: Vector2<Type>() {};
|
||||||
|
|
||||||
|
template<class CastedType>
|
||||||
|
requires std::is_arithmetic_v<CastedType>
|
||||||
|
[[nodiscard]] constexpr explicit operator Vector3<CastedType>() const noexcept
|
||||||
|
{
|
||||||
|
return {static_cast<CastedType>(this->x), static_cast<CastedType>(this->y),
|
||||||
|
static_cast<CastedType>(this->z)};
|
||||||
|
}
|
||||||
[[nodiscard]] constexpr bool operator==(const Vector3& other) const noexcept
|
[[nodiscard]] constexpr bool operator==(const Vector3& other) const noexcept
|
||||||
{
|
{
|
||||||
return Vector2<Type>::operator==(other) && (other.z == z);
|
return Vector2<Type>::operator==(other) && (other.z == z);
|
||||||
|
|||||||
@@ -21,6 +21,15 @@ namespace omath
|
|||||||
}
|
}
|
||||||
constexpr Vector4() noexcept: Vector3<Type>(), w(static_cast<Type>(0)) {};
|
constexpr Vector4() noexcept: Vector3<Type>(), w(static_cast<Type>(0)) {};
|
||||||
|
|
||||||
|
|
||||||
|
template<class CastedType>
|
||||||
|
requires std::is_arithmetic_v<CastedType>
|
||||||
|
[[nodiscard]] constexpr explicit operator Vector4<CastedType>() const noexcept
|
||||||
|
{
|
||||||
|
return {static_cast<CastedType>(this->x), static_cast<CastedType>(this->y),
|
||||||
|
static_cast<CastedType>(this->z), static_cast<CastedType>(this->w)};
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
constexpr bool operator==(const Vector4& other) const noexcept
|
constexpr bool operator==(const Vector4& other) const noexcept
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -368,6 +368,64 @@ TEST_F(UnitTestVector2, GreaterEqualOperator)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ── Cast operator tests ──────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
TEST(Vector2Cast, FloatToDouble)
|
||||||
|
{
|
||||||
|
constexpr Vector2<float> v{1.5f, -2.5f};
|
||||||
|
constexpr auto result = static_cast<Vector2<double>>(v);
|
||||||
|
EXPECT_DOUBLE_EQ(result.x, 1.5);
|
||||||
|
EXPECT_DOUBLE_EQ(result.y, -2.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Vector2Cast, DoubleToFloat)
|
||||||
|
{
|
||||||
|
constexpr Vector2<double> v{1.25, -3.75};
|
||||||
|
constexpr auto result = static_cast<Vector2<float>>(v);
|
||||||
|
EXPECT_FLOAT_EQ(result.x, 1.25f);
|
||||||
|
EXPECT_FLOAT_EQ(result.y, -3.75f);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Vector2Cast, FloatToInt_Truncates)
|
||||||
|
{
|
||||||
|
constexpr Vector2<float> v{3.9f, -2.1f};
|
||||||
|
constexpr auto result = static_cast<Vector2<int>>(v);
|
||||||
|
EXPECT_EQ(result.x, 3);
|
||||||
|
EXPECT_EQ(result.y, -2);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Vector2Cast, IntToFloat_Exact)
|
||||||
|
{
|
||||||
|
constexpr Vector2<int> v{7, -4};
|
||||||
|
constexpr auto result = static_cast<Vector2<float>>(v);
|
||||||
|
EXPECT_FLOAT_EQ(result.x, 7.f);
|
||||||
|
EXPECT_FLOAT_EQ(result.y, -4.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Vector2Cast, ZeroPreserved)
|
||||||
|
{
|
||||||
|
constexpr Vector2<float> v{0.f, 0.f};
|
||||||
|
constexpr auto result = static_cast<Vector2<double>>(v);
|
||||||
|
EXPECT_DOUBLE_EQ(result.x, 0.0);
|
||||||
|
EXPECT_DOUBLE_EQ(result.y, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Vector2Cast, NegativeValues)
|
||||||
|
{
|
||||||
|
constexpr Vector2<double> v{-100.0, -200.0};
|
||||||
|
constexpr auto result = static_cast<Vector2<float>>(v);
|
||||||
|
EXPECT_FLOAT_EQ(result.x, -100.f);
|
||||||
|
EXPECT_FLOAT_EQ(result.y, -200.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Vector2Cast, SameTypeRoundtrip)
|
||||||
|
{
|
||||||
|
constexpr Vector2<float> v{1.f, 2.f};
|
||||||
|
constexpr auto result = static_cast<Vector2<float>>(v);
|
||||||
|
EXPECT_FLOAT_EQ(result.x, v.x);
|
||||||
|
EXPECT_FLOAT_EQ(result.y, v.y);
|
||||||
|
}
|
||||||
|
|
||||||
// Static assertions (compile-time checks)
|
// Static assertions (compile-time checks)
|
||||||
static_assert(Vector2(1.0f, 2.0f).length_sqr() == 5.0f, "LengthSqr should be 5");
|
static_assert(Vector2(1.0f, 2.0f).length_sqr() == 5.0f, "LengthSqr should be 5");
|
||||||
static_assert(Vector2(1.0f, 2.0f).dot(Vector2(4.0f, 5.0f)) == 14.0f, "Dot product should be 14");
|
static_assert(Vector2(1.0f, 2.0f).dot(Vector2(4.0f, 5.0f)) == 14.0f, "Dot product should be 14");
|
||||||
|
|||||||
@@ -480,6 +480,71 @@ TEST_F(UnitTestVector3, GreaterEqualOperator)
|
|||||||
EXPECT_TRUE(omath::Vector3(1.f, 1.f, 1.f) >= omath::Vector3<float>{});
|
EXPECT_TRUE(omath::Vector3(1.f, 1.f, 1.f) >= omath::Vector3<float>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── Cast operator tests ──────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
TEST(Vector3Cast, FloatToDouble)
|
||||||
|
{
|
||||||
|
constexpr Vector3<float> v{1.5f, -2.5f, 3.0f};
|
||||||
|
constexpr auto result = static_cast<Vector3<double>>(v);
|
||||||
|
EXPECT_DOUBLE_EQ(result.x, 1.5);
|
||||||
|
EXPECT_DOUBLE_EQ(result.y, -2.5);
|
||||||
|
EXPECT_DOUBLE_EQ(result.z, 3.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Vector3Cast, DoubleToFloat)
|
||||||
|
{
|
||||||
|
constexpr Vector3<double> v{1.25, -3.75, 0.5};
|
||||||
|
constexpr auto result = static_cast<Vector3<float>>(v);
|
||||||
|
EXPECT_FLOAT_EQ(result.x, 1.25f);
|
||||||
|
EXPECT_FLOAT_EQ(result.y, -3.75f);
|
||||||
|
EXPECT_FLOAT_EQ(result.z, 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Vector3Cast, FloatToInt_Truncates)
|
||||||
|
{
|
||||||
|
constexpr Vector3<float> v{3.9f, -2.1f, 7.7f};
|
||||||
|
constexpr auto result = static_cast<Vector3<int>>(v);
|
||||||
|
EXPECT_EQ(result.x, 3);
|
||||||
|
EXPECT_EQ(result.y, -2);
|
||||||
|
EXPECT_EQ(result.z, 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Vector3Cast, IntToFloat_Exact)
|
||||||
|
{
|
||||||
|
constexpr Vector3<int> v{7, -4, 0};
|
||||||
|
constexpr auto result = static_cast<Vector3<float>>(v);
|
||||||
|
EXPECT_FLOAT_EQ(result.x, 7.f);
|
||||||
|
EXPECT_FLOAT_EQ(result.y, -4.f);
|
||||||
|
EXPECT_FLOAT_EQ(result.z, 0.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Vector3Cast, ZeroPreserved)
|
||||||
|
{
|
||||||
|
constexpr Vector3<float> v{0.f, 0.f, 0.f};
|
||||||
|
constexpr auto result = static_cast<Vector3<double>>(v);
|
||||||
|
EXPECT_DOUBLE_EQ(result.x, 0.0);
|
||||||
|
EXPECT_DOUBLE_EQ(result.y, 0.0);
|
||||||
|
EXPECT_DOUBLE_EQ(result.z, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Vector3Cast, NegativeValues)
|
||||||
|
{
|
||||||
|
constexpr Vector3<double> v{-100.0, -200.0, -300.0};
|
||||||
|
constexpr auto result = static_cast<Vector3<float>>(v);
|
||||||
|
EXPECT_FLOAT_EQ(result.x, -100.f);
|
||||||
|
EXPECT_FLOAT_EQ(result.y, -200.f);
|
||||||
|
EXPECT_FLOAT_EQ(result.z, -300.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Vector3Cast, SameTypeRoundtrip)
|
||||||
|
{
|
||||||
|
constexpr Vector3<float> v{1.f, 2.f, 3.f};
|
||||||
|
constexpr auto result = static_cast<Vector3<float>>(v);
|
||||||
|
EXPECT_FLOAT_EQ(result.x, v.x);
|
||||||
|
EXPECT_FLOAT_EQ(result.y, v.y);
|
||||||
|
EXPECT_FLOAT_EQ(result.z, v.z);
|
||||||
|
}
|
||||||
|
|
||||||
// Static assertions (compile-time checks)
|
// Static assertions (compile-time checks)
|
||||||
static_assert(Vector3(1.0f, 2.0f, 3.0f).length_sqr() == 14.0f, "LengthSqr should be 14");
|
static_assert(Vector3(1.0f, 2.0f, 3.0f).length_sqr() == 14.0f, "LengthSqr should be 14");
|
||||||
static_assert(Vector3(1.0f, 2.0f, 3.0f).dot(Vector3(4.0f, 5.0f, 6.0f)) == 32.0f, "Dot product should be 32");
|
static_assert(Vector3(1.0f, 2.0f, 3.0f).dot(Vector3(4.0f, 5.0f, 6.0f)) == 32.0f, "Dot product should be 32");
|
||||||
|
|||||||
@@ -260,4 +260,78 @@ TEST_F(UnitTestVector4, GreaterEqualOperator)
|
|||||||
{
|
{
|
||||||
EXPECT_TRUE(omath::Vector4<float>{} >= omath::Vector4<float>{});
|
EXPECT_TRUE(omath::Vector4<float>{} >= omath::Vector4<float>{});
|
||||||
EXPECT_TRUE(omath::Vector4(1.f, 1.f, 1.f, 1.f) >= omath::Vector4<float>{});
|
EXPECT_TRUE(omath::Vector4(1.f, 1.f, 1.f, 1.f) >= omath::Vector4<float>{});
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Cast operator tests ──────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
using namespace omath;
|
||||||
|
|
||||||
|
TEST(Vector4Cast, FloatToDouble)
|
||||||
|
{
|
||||||
|
constexpr Vector4<float> v{1.5f, -2.5f, 3.0f, 4.25f};
|
||||||
|
constexpr auto result = static_cast<Vector4<double>>(v);
|
||||||
|
EXPECT_DOUBLE_EQ(result.x, 1.5);
|
||||||
|
EXPECT_DOUBLE_EQ(result.y, -2.5);
|
||||||
|
EXPECT_DOUBLE_EQ(result.z, 3.0);
|
||||||
|
EXPECT_DOUBLE_EQ(result.w, 4.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Vector4Cast, DoubleToFloat)
|
||||||
|
{
|
||||||
|
constexpr Vector4<double> v{1.25, -3.75, 0.5, -0.125};
|
||||||
|
constexpr auto result = static_cast<Vector4<float>>(v);
|
||||||
|
EXPECT_FLOAT_EQ(result.x, 1.25f);
|
||||||
|
EXPECT_FLOAT_EQ(result.y, -3.75f);
|
||||||
|
EXPECT_FLOAT_EQ(result.z, 0.5f);
|
||||||
|
EXPECT_FLOAT_EQ(result.w, -0.125f);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Vector4Cast, FloatToInt_Truncates)
|
||||||
|
{
|
||||||
|
constexpr Vector4<float> v{3.9f, -2.1f, 7.7f, -0.9f};
|
||||||
|
constexpr auto result = static_cast<Vector4<int>>(v);
|
||||||
|
EXPECT_EQ(result.x, 3);
|
||||||
|
EXPECT_EQ(result.y, -2);
|
||||||
|
EXPECT_EQ(result.z, 7);
|
||||||
|
EXPECT_EQ(result.w, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Vector4Cast, IntToFloat_Exact)
|
||||||
|
{
|
||||||
|
constexpr Vector4<int> v{7, -4, 0, 1};
|
||||||
|
constexpr auto result = static_cast<Vector4<float>>(v);
|
||||||
|
EXPECT_FLOAT_EQ(result.x, 7.f);
|
||||||
|
EXPECT_FLOAT_EQ(result.y, -4.f);
|
||||||
|
EXPECT_FLOAT_EQ(result.z, 0.f);
|
||||||
|
EXPECT_FLOAT_EQ(result.w, 1.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Vector4Cast, ZeroPreserved)
|
||||||
|
{
|
||||||
|
constexpr Vector4<float> v{0.f, 0.f, 0.f, 0.f};
|
||||||
|
constexpr auto result = static_cast<Vector4<double>>(v);
|
||||||
|
EXPECT_DOUBLE_EQ(result.x, 0.0);
|
||||||
|
EXPECT_DOUBLE_EQ(result.y, 0.0);
|
||||||
|
EXPECT_DOUBLE_EQ(result.z, 0.0);
|
||||||
|
EXPECT_DOUBLE_EQ(result.w, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Vector4Cast, NegativeValues)
|
||||||
|
{
|
||||||
|
constexpr Vector4<double> v{-100.0, -200.0, -300.0, -400.0};
|
||||||
|
constexpr auto result = static_cast<Vector4<float>>(v);
|
||||||
|
EXPECT_FLOAT_EQ(result.x, -100.f);
|
||||||
|
EXPECT_FLOAT_EQ(result.y, -200.f);
|
||||||
|
EXPECT_FLOAT_EQ(result.z, -300.f);
|
||||||
|
EXPECT_FLOAT_EQ(result.w, -400.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Vector4Cast, SameTypeRoundtrip)
|
||||||
|
{
|
||||||
|
constexpr Vector4<float> v{1.f, 2.f, 3.f, 4.f};
|
||||||
|
constexpr auto result = static_cast<Vector4<float>>(v);
|
||||||
|
EXPECT_FLOAT_EQ(result.x, v.x);
|
||||||
|
EXPECT_FLOAT_EQ(result.y, v.y);
|
||||||
|
EXPECT_FLOAT_EQ(result.z, v.z);
|
||||||
|
EXPECT_FLOAT_EQ(result.w, v.w);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user