From e64db02ac37436744fdcef9c303ae78ea0fa5021 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Sat, 25 Jul 2015 01:52:27 +0200 Subject: [PATCH] Fix cast<> method. Add vector_type to is_vec, because vector_type is private and it couldn't be used in cast. Besides if not is_vec, you can't expect to find vector_type. The conditional in the cast return type works like if V2 is not a Vec, you can just use V as the vector_type, anyways the first is_vec is false so the whole condition is going to be false anyways, even if it results that V == V. --- include/vectorwrapper/vectorwrapper.hpp | 51 +++++++++++++++---------- include/vectorwrapper/vectorwrapper.inl | 26 +++++++------ test/unit/sample_vectors.hpp | 4 ++ test/unit/test_conversions.cpp | 30 +++++++++++++++ 4 files changed, 79 insertions(+), 32 deletions(-) diff --git a/include/vectorwrapper/vectorwrapper.hpp b/include/vectorwrapper/vectorwrapper.hpp index 31a57d2..5b0b854 100644 --- a/include/vectorwrapper/vectorwrapper.hpp +++ b/include/vectorwrapper/vectorwrapper.hpp @@ -43,50 +43,59 @@ namespace vwr { template Vec& assign_same_type ( Vec& parLeft, const Vec& parRight ); - template ::dimensions, std::size_t US=VectorWrapperInfo::dimensions> struct have_same_offsets { + template ::dimensions, std::size_t US=VectorWrapperInfo::dimensions> struct have_compat_offsets { enum { value = false }; }; - template struct have_same_offsets { + template struct have_compat_offsets { enum { - value = (VectorWrapperInfo::offset_x == VectorWrapperInfo::offset_x) + value = true }; }; - template struct have_same_offsets { + template struct have_compat_offsets { enum { - value = (VectorWrapperInfo::offset_x == VectorWrapperInfo::offset_x) and - (VectorWrapperInfo::offset_y == VectorWrapperInfo::offset_y) + value = + VectorWrapperInfo::offset_y - VectorWrapperInfo::offset_x == + VectorWrapperInfo::offset_y - VectorWrapperInfo::offset_x }; }; - template struct have_same_offsets { + template struct have_compat_offsets { enum { - value = (VectorWrapperInfo::offset_x == VectorWrapperInfo::offset_x) and - (VectorWrapperInfo::offset_y == VectorWrapperInfo::offset_y) and - (VectorWrapperInfo::offset_z == VectorWrapperInfo::offset_z) + value = + VectorWrapperInfo::offset_y - VectorWrapperInfo::offset_x == + VectorWrapperInfo::offset_y - VectorWrapperInfo::offset_x and + VectorWrapperInfo::offset_z - VectorWrapperInfo::offset_x == + VectorWrapperInfo::offset_z - VectorWrapperInfo::offset_x }; }; - template struct have_same_offsets { + template struct have_compat_offsets { enum { - value = (VectorWrapperInfo::offset_x == VectorWrapperInfo::offset_x) and - (VectorWrapperInfo::offset_y == VectorWrapperInfo::offset_y) and - (VectorWrapperInfo::offset_z == VectorWrapperInfo::offset_z) and - (VectorWrapperInfo::offset_w == VectorWrapperInfo::offset_w) + value = + VectorWrapperInfo::offset_y - VectorWrapperInfo::offset_x == + VectorWrapperInfo::offset_y - VectorWrapperInfo::offset_x and + VectorWrapperInfo::offset_z - VectorWrapperInfo::offset_x == + VectorWrapperInfo::offset_z - VectorWrapperInfo::offset_x and + VectorWrapperInfo::offset_w - VectorWrapperInfo::offset_x == + VectorWrapperInfo::offset_w - VectorWrapperInfo::offset_x }; }; template - struct have_same_layout { + struct have_compat_layout { enum { value = HasOffsetXEnum>::value and HasOffsetXEnum>::value and - VectorWrapperInfo::dimensions == VectorWrapperInfo::dimensions and - have_same_offsets::value + static_cast(VectorWrapperInfo::dimensions) == + static_cast(VectorWrapperInfo::dimensions) and + have_compat_offsets::value }; }; template struct is_vec { + typedef void vector_type; enum { value = false }; }; template struct is_vec> { + typedef V vector_type; enum { value = true }; }; @@ -103,7 +112,7 @@ namespace vwr { VecBase ( void ) = default; template - explicit VecBase ( const typename std::enable_if::value and not std::is_same::value, T>::type& parInit ); + explicit VecBase ( const T& parInit, typename std::enable_if::value and not std::is_same::value, bool>::type=false ); explicit VecBase ( const vector_type& parInit ); template VecBase ( scalar_type parX, scalar_type parY, Args... parArgs ); @@ -118,9 +127,9 @@ namespace vwr { const vector_type& data ( void ) const { return m_wrapped; } template - const typename std::enable_if::value and have_same_layout::value, V2>::type& cast ( void ) const; + const typename std::enable_if::value and have_compat_layout::value, typename is_vec::vector_type, V>::type>::value and sizeof(V2) <= sizeof(V), V2>::type& cast ( void ) const; template - typename std::enable_if::value and have_same_layout::value, V2>::type& cast ( void ); + typename std::enable_if::value and have_compat_layout::value, typename is_vec::vector_type, V>::type>::value and sizeof(V2) <= sizeof(V), V2>::type& cast ( void ); template VecBase& operator+= ( const VecBase& parOther ); template VecBase& operator-= ( const VecBase& parOther ); diff --git a/include/vectorwrapper/vectorwrapper.inl b/include/vectorwrapper/vectorwrapper.inl index bd746a9..f96b216 100644 --- a/include/vectorwrapper/vectorwrapper.inl +++ b/include/vectorwrapper/vectorwrapper.inl @@ -18,18 +18,18 @@ namespace vwr { namespace implem { template template - VecBase::VecBase (const typename std::enable_if::value and not std::is_same::value, T>::type& parInit) : - m_wrapped(parInit) - { - } - - template - VecBase::VecBase (const vector_type& parInit) { + VecBase::VecBase (const T& parInit, typename std::enable_if::value and not std::is_same::value, bool>::type) { for (int z = 0; z < VectorWrapperInfo::dimensions; ++z) { VecGetter::get_at(m_wrapped, z) = parInit; } } + template + VecBase::VecBase (const vector_type& parInit) : + m_wrapped(parInit) + { + } + template template VecBase::VecBase (scalar_type parX, scalar_type parY, Args... parArgs) { @@ -67,14 +67,18 @@ namespace vwr { template template - const typename std::enable_if::value and have_same_layout::value, V2>::type& VecBase::cast() const { - return *reinterpret_cast(this); + const typename std::enable_if::value and have_compat_layout::value, typename is_vec::vector_type, V>::type>::value and sizeof(V2) <= sizeof(V), V2>::type& VecBase::cast() const { + return *reinterpret_cast( + reinterpret_cast(this) + VectorWrapperInfo::offset_x + ); } template template - typename std::enable_if::value and have_same_layout::value, V2>::type& VecBase::cast() { - return *reinterpret_cast(this); + typename std::enable_if::value and have_compat_layout::value, typename is_vec::vector_type, V>::type>::value and sizeof(V2) <= sizeof(V), V2>::type& VecBase::cast() { + return *reinterpret_cast( + reinterpret_cast(this) + VectorWrapperInfo::offset_x + ); } template diff --git a/test/unit/sample_vectors.hpp b/test/unit/sample_vectors.hpp index 38661d8..0c31040 100644 --- a/test/unit/sample_vectors.hpp +++ b/test/unit/sample_vectors.hpp @@ -166,6 +166,10 @@ namespace vwr { //Vector Wrapper debug assertions static_assert(not implem::HasOffsetXEnum>::value, "Should return false"); static_assert(implem::HasOffsetXEnum>::value, "Should return true"); + static_assert(implem::have_compat_offsets::value, "Should be true"); + static_assert(implem::have_compat_layout::value, "Should be true"); + static_assert(implem::is_vec::value, "Should be true"); + static_assert(implem::is_vec::value, "Should be true"); } //namespace vwr #endif diff --git a/test/unit/test_conversions.cpp b/test/unit/test_conversions.cpp index c976f92..5de8086 100644 --- a/test/unit/test_conversions.cpp +++ b/test/unit/test_conversions.cpp @@ -1,6 +1,12 @@ #include "sample_vectors.hpp" #include +void test_svec3 (const vwr::svec3& parVec, float parX, float parY, float parZ) { + EXPECT_EQ(parVec.x(), parX); + EXPECT_EQ(parVec.y(), parY); + EXPECT_EQ(parVec.z(), parZ); +} + TEST(vwr, conversion) { using namespace vwr; @@ -12,5 +18,29 @@ TEST(vwr, conversion) { static_assert(std::is_same::value, "Expecting svec2"); EXPECT_EQ(s2.x(), s.x()); EXPECT_EQ(s2.y(), 1.0f); + + auto s3 = s2.xyn(2.0f); + EXPECT_EQ(s3.x(), s2.x()); + EXPECT_EQ(s3.y(), s2.y()); + EXPECT_EQ(s3.z(), 2.0f); + + const auto s3_copy(s3); + EXPECT_EQ(s3_copy, s3); + } + + { + svec3 s3(1.0f); + mvec3 m3(s3); + EXPECT_EQ(m3.x(), 1.0f); + EXPECT_EQ(m3.y(), 1.0f); + EXPECT_EQ(m3.z(), 1.0f); + EXPECT_EQ(m3.data().x, 1.0f); + EXPECT_EQ(m3.data().y, 1.0f); + EXPECT_EQ(m3.data().z, 1.0f); + } + + { + pvec3 p3(1.0f, 2.0f, 3.0f); + test_svec3(p3.cast(), p3.x(), p3.y(), p3.z()); } }