Allow casting to vectors of lower dimensions.

This commit is contained in:
King_DuckZ 2015-07-25 21:18:45 +02:00
parent fe03f45f76
commit 7affd7960f
3 changed files with 28 additions and 11 deletions

View File

@ -71,22 +71,29 @@ namespace vwr {
enum { value = get_offset_enum_from_index<T, 0>::value };
};
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 };
};
template <typename T, typename U> struct have_compat_offsets<T, U, 1, 1> {
template <
typename T,
typename U,
std::size_t S=(
static_cast<int>(VectorWrapperInfo<T>::dimensions) < static_cast<int>(VectorWrapperInfo<U>::dimensions) ?
static_cast<int>(VectorWrapperInfo<T>::dimensions)
:
static_cast<int>(VectorWrapperInfo<U>::dimensions)
)
> struct have_compat_offsets;
template <typename T, typename U> struct have_compat_offsets<T, U, 1> {
enum {
value = true
};
};
template <typename T, typename U> struct have_compat_offsets<T, U, 2, 2> {
template <typename T, typename U> struct have_compat_offsets<T, U, 2> {
enum {
value =
VectorWrapperInfo<T>::offset_x - min_offset<T>::value == VectorWrapperInfo<U>::offset_x - min_offset<U>::value and
VectorWrapperInfo<T>::offset_y - min_offset<T>::value == VectorWrapperInfo<U>::offset_y - min_offset<U>::value
};
};
template <typename T, typename U> struct have_compat_offsets<T, U, 3, 3> {
template <typename T, typename U> struct have_compat_offsets<T, U, 3> {
enum {
value =
VectorWrapperInfo<T>::offset_x - min_offset<T>::value == VectorWrapperInfo<U>::offset_x - min_offset<U>::value and
@ -94,7 +101,7 @@ namespace vwr {
VectorWrapperInfo<T>::offset_z - min_offset<T>::value == VectorWrapperInfo<U>::offset_z - min_offset<U>::value
};
};
template <typename T, typename U> struct have_compat_offsets<T, U, 4, 4> {
template <typename T, typename U> struct have_compat_offsets<T, U, 4> {
enum {
value =
VectorWrapperInfo<T>::offset_x - min_offset<T>::value == VectorWrapperInfo<U>::offset_x - min_offset<U>::value and
@ -108,9 +115,8 @@ namespace vwr {
struct have_compat_layout {
enum {
value =
HasOffsetXEnum<VectorWrapperInfo<T>>::value and HasOffsetXEnum<VectorWrapperInfo<U>>::value and
static_cast<int>(VectorWrapperInfo<T>::dimensions) ==
static_cast<int>(VectorWrapperInfo<U>::dimensions) and
HasOffsetXEnum<VectorWrapperInfo<T>>::value and
HasOffsetXEnum<VectorWrapperInfo<U>>::value and
have_compat_offsets<T, U>::value
};
};

View File

@ -79,7 +79,7 @@ namespace vwr {
//Assert that V2 won't stomp on part of V's data, unless the user
//has explicitly said he doesn't care.
static_assert((sizeof(typename VectorWrapperInfo<typename is_vec<V2>::vector_type>::scalar_type) * dimensions == sizeof(V2)) or
static_assert((sizeof(typename VectorWrapperInfo<typename is_vec<V2>::vector_type>::scalar_type) * VectorWrapperInfo<typename is_vec<V2>::vector_type>::dimensions == sizeof(V2)) or
IsCastIgnoreTrailingPropertiesSet<typename is_vec<V2>::vector_type>::value,
"V2 must not have any properties past the last coordinate");
static_assert(alignof(typename VectorWrapperInfo<V>::scalar_type) == alignof(V2), "Casting to V2 would give you a misaligned variable");

View File

@ -2,6 +2,11 @@
#include <gtest/gtest.h>
namespace {
void test_svec2 (const vwr::svec2& parVec, float parX, float parY) {
EXPECT_EQ(parVec.x(), parX);
EXPECT_EQ(parVec.y(), parY);
}
void simplevec_double (vwr::SimpleVector3& parVec, float parX, float parY, float parZ) {
EXPECT_EQ(parVec.x, parX);
EXPECT_EQ(parVec.y, parY);
@ -74,4 +79,10 @@ TEST(vwr, example) {
svec3 vec_b(vec);
EXPECT_EQ(vec_b, vec);
}
{
//You can also cast a svec3 to svec2, if you need to.
const svec3 vec(9.5f, 1.2f, 0.9f);
test_svec2(vec.cast<svec2>(), vec.x(), vec.y());
}
}