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.
This commit is contained in:
parent
59d8eb43e7
commit
e64db02ac3
4 changed files with 79 additions and 32 deletions
|
@ -43,50 +43,59 @@ namespace vwr {
|
||||||
template <typename V>
|
template <typename V>
|
||||||
Vec<V>& assign_same_type ( Vec<V>& parLeft, const Vec<V>& parRight );
|
Vec<V>& assign_same_type ( Vec<V>& parLeft, const Vec<V>& parRight );
|
||||||
|
|
||||||
template <typename T, typename U, std::size_t TS=VectorWrapperInfo<T>::dimensions, std::size_t US=VectorWrapperInfo<T>::dimensions> struct have_same_offsets {
|
template <typename T, typename U, std::size_t TS=VectorWrapperInfo<T>::dimensions, std::size_t US=VectorWrapperInfo<U>::dimensions> struct have_compat_offsets {
|
||||||
enum { value = false };
|
enum { value = false };
|
||||||
};
|
};
|
||||||
template <typename T, typename U> struct have_same_offsets<T, U, 1, 1> {
|
template <typename T, typename U> struct have_compat_offsets<T, U, 1, 1> {
|
||||||
enum {
|
enum {
|
||||||
value = (VectorWrapperInfo<T>::offset_x == VectorWrapperInfo<U>::offset_x)
|
value = true
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
template <typename T, typename U> struct have_same_offsets<T, U, 2, 2> {
|
template <typename T, typename U> struct have_compat_offsets<T, U, 2, 2> {
|
||||||
enum {
|
enum {
|
||||||
value = (VectorWrapperInfo<T>::offset_x == VectorWrapperInfo<U>::offset_x) and
|
value =
|
||||||
(VectorWrapperInfo<T>::offset_y == VectorWrapperInfo<U>::offset_y)
|
VectorWrapperInfo<T>::offset_y - VectorWrapperInfo<T>::offset_x ==
|
||||||
|
VectorWrapperInfo<U>::offset_y - VectorWrapperInfo<U>::offset_x
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
template <typename T, typename U> struct have_same_offsets<T, U, 3, 3> {
|
template <typename T, typename U> struct have_compat_offsets<T, U, 3, 3> {
|
||||||
enum {
|
enum {
|
||||||
value = (VectorWrapperInfo<T>::offset_x == VectorWrapperInfo<U>::offset_x) and
|
value =
|
||||||
(VectorWrapperInfo<T>::offset_y == VectorWrapperInfo<U>::offset_y) and
|
VectorWrapperInfo<T>::offset_y - VectorWrapperInfo<T>::offset_x ==
|
||||||
(VectorWrapperInfo<T>::offset_z == VectorWrapperInfo<U>::offset_z)
|
VectorWrapperInfo<U>::offset_y - VectorWrapperInfo<U>::offset_x and
|
||||||
|
VectorWrapperInfo<T>::offset_z - VectorWrapperInfo<T>::offset_x ==
|
||||||
|
VectorWrapperInfo<U>::offset_z - VectorWrapperInfo<U>::offset_x
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
template <typename T, typename U> struct have_same_offsets<T, U, 4, 4> {
|
template <typename T, typename U> struct have_compat_offsets<T, U, 4, 4> {
|
||||||
enum {
|
enum {
|
||||||
value = (VectorWrapperInfo<T>::offset_x == VectorWrapperInfo<U>::offset_x) and
|
value =
|
||||||
(VectorWrapperInfo<T>::offset_y == VectorWrapperInfo<U>::offset_y) and
|
VectorWrapperInfo<T>::offset_y - VectorWrapperInfo<T>::offset_x ==
|
||||||
(VectorWrapperInfo<T>::offset_z == VectorWrapperInfo<U>::offset_z) and
|
VectorWrapperInfo<U>::offset_y - VectorWrapperInfo<U>::offset_x and
|
||||||
(VectorWrapperInfo<T>::offset_w == VectorWrapperInfo<U>::offset_w)
|
VectorWrapperInfo<T>::offset_z - VectorWrapperInfo<T>::offset_x ==
|
||||||
|
VectorWrapperInfo<U>::offset_z - VectorWrapperInfo<U>::offset_x and
|
||||||
|
VectorWrapperInfo<T>::offset_w - VectorWrapperInfo<T>::offset_x ==
|
||||||
|
VectorWrapperInfo<U>::offset_w - VectorWrapperInfo<U>::offset_x
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename U>
|
template <typename T, typename U>
|
||||||
struct have_same_layout {
|
struct have_compat_layout {
|
||||||
enum {
|
enum {
|
||||||
value =
|
value =
|
||||||
HasOffsetXEnum<VectorWrapperInfo<T>>::value and HasOffsetXEnum<VectorWrapperInfo<U>>::value and
|
HasOffsetXEnum<VectorWrapperInfo<T>>::value and HasOffsetXEnum<VectorWrapperInfo<U>>::value and
|
||||||
VectorWrapperInfo<T>::dimensions == VectorWrapperInfo<U>::dimensions and
|
static_cast<int>(VectorWrapperInfo<T>::dimensions) ==
|
||||||
have_same_offsets<T, U>::value
|
static_cast<int>(VectorWrapperInfo<U>::dimensions) and
|
||||||
|
have_compat_offsets<T, U>::value
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename V> struct is_vec {
|
template <typename V> struct is_vec {
|
||||||
|
typedef void vector_type;
|
||||||
enum { value = false };
|
enum { value = false };
|
||||||
};
|
};
|
||||||
template <typename V> struct is_vec<Vec<V>> {
|
template <typename V> struct is_vec<Vec<V>> {
|
||||||
|
typedef V vector_type;
|
||||||
enum { value = true };
|
enum { value = true };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -103,7 +112,7 @@ namespace vwr {
|
||||||
|
|
||||||
VecBase ( void ) = default;
|
VecBase ( void ) = default;
|
||||||
template <typename T>
|
template <typename T>
|
||||||
explicit VecBase ( const typename std::enable_if<std::is_same<T, scalar_type>::value and not std::is_same<scalar_type, vector_type>::value, T>::type& parInit );
|
explicit VecBase ( const T& parInit, typename std::enable_if<std::is_same<T, scalar_type>::value and not std::is_same<scalar_type, vector_type>::value, bool>::type=false );
|
||||||
explicit VecBase ( const vector_type& parInit );
|
explicit VecBase ( const vector_type& parInit );
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
VecBase ( scalar_type parX, scalar_type parY, Args... parArgs );
|
VecBase ( scalar_type parX, scalar_type parY, Args... parArgs );
|
||||||
|
@ -118,9 +127,9 @@ namespace vwr {
|
||||||
const vector_type& data ( void ) const { return m_wrapped; }
|
const vector_type& data ( void ) const { return m_wrapped; }
|
||||||
|
|
||||||
template <typename V2>
|
template <typename V2>
|
||||||
const typename std::enable_if<is_vec<V2>::value and have_same_layout<V, typename V2::vector_type>::value, V2>::type& cast ( void ) const;
|
const typename std::enable_if<is_vec<V2>::value and have_compat_layout<V, typename std::conditional<is_vec<V2>::value, typename is_vec<V2>::vector_type, V>::type>::value and sizeof(V2) <= sizeof(V), V2>::type& cast ( void ) const;
|
||||||
template <typename V2>
|
template <typename V2>
|
||||||
typename std::enable_if<is_vec<V2>::value and have_same_layout<V, typename V2::vector_type>::value, V2>::type& cast ( void );
|
typename std::enable_if<is_vec<V2>::value and have_compat_layout<V, typename std::conditional<is_vec<V2>::value, typename is_vec<V2>::vector_type, V>::type>::value and sizeof(V2) <= sizeof(V), V2>::type& cast ( void );
|
||||||
|
|
||||||
template <typename V2> VecBase& operator+= ( const VecBase<V2>& parOther );
|
template <typename V2> VecBase& operator+= ( const VecBase<V2>& parOther );
|
||||||
template <typename V2> VecBase& operator-= ( const VecBase<V2>& parOther );
|
template <typename V2> VecBase& operator-= ( const VecBase<V2>& parOther );
|
||||||
|
|
|
@ -18,18 +18,18 @@ namespace vwr {
|
||||||
namespace implem {
|
namespace implem {
|
||||||
template <typename V>
|
template <typename V>
|
||||||
template <typename T>
|
template <typename T>
|
||||||
VecBase<V>::VecBase (const typename std::enable_if<std::is_same<T, scalar_type>::value and not std::is_same<scalar_type, vector_type>::value, T>::type& parInit) :
|
VecBase<V>::VecBase (const T& parInit, typename std::enable_if<std::is_same<T, scalar_type>::value and not std::is_same<scalar_type, vector_type>::value, bool>::type) {
|
||||||
m_wrapped(parInit)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename V>
|
|
||||||
VecBase<V>::VecBase (const vector_type& parInit) {
|
|
||||||
for (int z = 0; z < VectorWrapperInfo<V>::dimensions; ++z) {
|
for (int z = 0; z < VectorWrapperInfo<V>::dimensions; ++z) {
|
||||||
VecGetter<V>::get_at(m_wrapped, z) = parInit;
|
VecGetter<V>::get_at(m_wrapped, z) = parInit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename V>
|
||||||
|
VecBase<V>::VecBase (const vector_type& parInit) :
|
||||||
|
m_wrapped(parInit)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
template <typename V>
|
template <typename V>
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
VecBase<V>::VecBase (scalar_type parX, scalar_type parY, Args... parArgs) {
|
VecBase<V>::VecBase (scalar_type parX, scalar_type parY, Args... parArgs) {
|
||||||
|
@ -67,14 +67,18 @@ namespace vwr {
|
||||||
|
|
||||||
template <typename V>
|
template <typename V>
|
||||||
template <typename V2>
|
template <typename V2>
|
||||||
const typename std::enable_if<is_vec<V2>::value and have_same_layout<V, typename V2::vector_type>::value, V2>::type& VecBase<V>::cast() const {
|
const typename std::enable_if<is_vec<V2>::value and have_compat_layout<V, typename std::conditional<is_vec<V2>::value, typename is_vec<V2>::vector_type, V>::type>::value and sizeof(V2) <= sizeof(V), V2>::type& VecBase<V>::cast() const {
|
||||||
return *reinterpret_cast<const V2*>(this);
|
return *reinterpret_cast<const V2*>(
|
||||||
|
reinterpret_cast<const char*>(this) + VectorWrapperInfo<V>::offset_x
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename V>
|
template <typename V>
|
||||||
template <typename V2>
|
template <typename V2>
|
||||||
typename std::enable_if<is_vec<V2>::value and have_same_layout<V, typename V2::vector_type>::value, V2>::type& VecBase<V>::cast() {
|
typename std::enable_if<is_vec<V2>::value and have_compat_layout<V, typename std::conditional<is_vec<V2>::value, typename is_vec<V2>::vector_type, V>::type>::value and sizeof(V2) <= sizeof(V), V2>::type& VecBase<V>::cast() {
|
||||||
return *reinterpret_cast<V2*>(this);
|
return *reinterpret_cast<V2*>(
|
||||||
|
reinterpret_cast<char*>(this) + VectorWrapperInfo<V>::offset_x
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename V>
|
template <typename V>
|
||||||
|
|
|
@ -166,6 +166,10 @@ namespace vwr {
|
||||||
//Vector Wrapper debug assertions
|
//Vector Wrapper debug assertions
|
||||||
static_assert(not implem::HasOffsetXEnum<VectorWrapperInfo<float>>::value, "Should return false");
|
static_assert(not implem::HasOffsetXEnum<VectorWrapperInfo<float>>::value, "Should return false");
|
||||||
static_assert(implem::HasOffsetXEnum<VectorWrapperInfo<SimpleVector2>>::value, "Should return true");
|
static_assert(implem::HasOffsetXEnum<VectorWrapperInfo<SimpleVector2>>::value, "Should return true");
|
||||||
|
static_assert(implem::have_compat_offsets<SimpleVector3, PaddedVector3>::value, "Should be true");
|
||||||
|
static_assert(implem::have_compat_layout<SimpleVector3, PaddedVector3>::value, "Should be true");
|
||||||
|
static_assert(implem::is_vec<pvec3>::value, "Should be true");
|
||||||
|
static_assert(implem::is_vec<svec3>::value, "Should be true");
|
||||||
} //namespace vwr
|
} //namespace vwr
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
#include "sample_vectors.hpp"
|
#include "sample_vectors.hpp"
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
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) {
|
TEST(vwr, conversion) {
|
||||||
using namespace vwr;
|
using namespace vwr;
|
||||||
|
|
||||||
|
@ -12,5 +18,29 @@ TEST(vwr, conversion) {
|
||||||
static_assert(std::is_same<decltype(s2), svec2>::value, "Expecting svec2");
|
static_assert(std::is_same<decltype(s2), svec2>::value, "Expecting svec2");
|
||||||
EXPECT_EQ(s2.x(), s.x());
|
EXPECT_EQ(s2.x(), s.x());
|
||||||
EXPECT_EQ(s2.y(), 1.0f);
|
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<svec3>(), p3.x(), p3.y(), p3.z());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue