Add Vec1Promotion.

This commit is contained in:
King_DuckZ 2015-07-25 00:55:57 +02:00
parent d3b63aab8c
commit 30371adba9
3 changed files with 57 additions and 9 deletions

View file

@ -172,6 +172,20 @@ namespace vwr {
static typename VectorWrapperInfo<T>::scalar_type& get_at ( T& parVec, std::size_t parIndex ); static typename VectorWrapperInfo<T>::scalar_type& get_at ( T& parVec, std::size_t parIndex );
}; };
template <typename V, bool Enabled> struct Vec1Promotion;
template <typename V> struct Vec1Promotion<V, false> { };
template <typename V> struct Vec1Promotion<V, true> {
typedef Vec<typename VectorWrapperInfo<V>::higher_vector_type> higher_vector_type;
typedef typename VectorWrapperInfo<V>::scalar_type scalar_type;
static_assert(VectorWrapperInfo<typename VectorWrapperInfo<V>::higher_vector_type>::dimensions == 2, "Wrong promoted vector type");
higher_vector_type x1 ( void ) const { return xn(scalar_type(1)); }
higher_vector_type x0 ( void ) const { return xn(scalar_type(0)); }
higher_vector_type xn ( const scalar_type& parN ) const;
higher_vector_type nx ( const scalar_type& parN ) const;
};
template <typename V, bool Enabled> struct Vec2Promotion; template <typename V, bool Enabled> struct Vec2Promotion;
template <typename V> struct Vec2Promotion<V, false> {}; template <typename V> struct Vec2Promotion<V, false> {};
template <typename V> struct Vec2Promotion<V, true> { template <typename V> struct Vec2Promotion<V, true> {
@ -180,9 +194,9 @@ namespace vwr {
static_assert(VectorWrapperInfo<typename VectorWrapperInfo<V>::higher_vector_type>::dimensions == 3, "Wrong promoted vector type"); static_assert(VectorWrapperInfo<typename VectorWrapperInfo<V>::higher_vector_type>::dimensions == 3, "Wrong promoted vector type");
higher_vector_type xy1 ( void ) const { return xyz(scalar_type(1)); } higher_vector_type xy1 ( void ) const { return xyn(scalar_type(1)); }
higher_vector_type xy0 ( void ) const { return xyz(scalar_type(0)); } higher_vector_type xy0 ( void ) const { return xyn(scalar_type(0)); }
higher_vector_type xyz ( const scalar_type& parZ ) const; higher_vector_type xyn ( const scalar_type& parZ ) const;
}; };
template <typename V, bool Enabled> struct Vec3Promotion; template <typename V, bool Enabled> struct Vec3Promotion;
@ -239,6 +253,13 @@ namespace vwr {
scalar_type& x ( void ); scalar_type& x ( void );
scalar_type& y ( void ); scalar_type& y ( void );
}; };
template <typename V>
struct VecAccessors<V, 1> : Vec1Promotion<V, HasHigherVecTypedef<VectorWrapperInfo<V>>::value> {
typedef typename VectorWrapperInfo<V>::scalar_type scalar_type;
scalar_type& x ( void );
const scalar_type& x ( void ) const;
};
} //namespace implem } //namespace implem
template <typename V, std::size_t S> template <typename V, std::size_t S>
@ -250,7 +271,8 @@ namespace vwr {
}; };
template <typename V> template <typename V>
class Vec<V, 1> : public implem::VecBase<V> { class Vec<V, 1> : public implem::VecBase<V>, public implem::VecAccessors<V, 1> {
static_assert(std::is_standard_layout<implem::VecBase<V>>::value, "Base class must be a standard layout type");
typedef typename implem::VecBase<V>::vector_type vector_type; typedef typename implem::VecBase<V>::vector_type vector_type;
typedef typename implem::VecBase<V>::scalar_type scalar_type; typedef typename implem::VecBase<V>::scalar_type scalar_type;
public: public:
@ -267,9 +289,6 @@ namespace vwr {
explicit Vec ( const typename std::enable_if<std::is_same<T, scalar_type>::value and not std::is_same<scalar_type, vector_type>::value, T>::type& parX ) : implem::VecBase<V>(parX) { } explicit Vec ( const typename std::enable_if<std::is_same<T, scalar_type>::value and not std::is_same<scalar_type, vector_type>::value, T>::type& parX ) : implem::VecBase<V>(parX) { }
template <typename V2> Vec ( const Vec<V2, dimensions>& parOther ) { implem::assign(*this, parOther); } template <typename V2> Vec ( const Vec<V2, dimensions>& parOther ) { implem::assign(*this, parOther); }
scalar_type& x ( void ) { return (*this)[0]; }
const scalar_type& x ( void ) const { return (*this)[0]; }
Vec& operator= ( const Vec& parOther ) { return implem::assign_same_type(*this, parOther); } Vec& operator= ( const Vec& parOther ) { return implem::assign_same_type(*this, parOther); }
template <typename V2> template <typename V2>
Vec& operator= ( const Vec<V2, dimensions>& parOther ) { return implem::assign(*this, parOther); } Vec& operator= ( const Vec<V2, dimensions>& parOther ) { return implem::assign(*this, parOther); }

View file

@ -164,9 +164,21 @@ namespace vwr {
} }
template <typename V> template <typename V>
auto Vec2Promotion<V, true>::xyz (const scalar_type& parZ) const -> higher_vector_type { auto Vec1Promotion<V, true>::xn (const scalar_type& parN) const -> higher_vector_type {
auto& this_vec = *static_cast<const Vec<V>*>(this); auto& this_vec = *static_cast<const Vec<V>*>(this);
return higher_vector_type(this_vec[0], this_vec[1], parZ); return higher_vector_type(this_vec[0], parN);
}
template <typename V>
auto Vec1Promotion<V, true>::nx (const scalar_type& parN) const -> higher_vector_type {
auto& this_vec = *static_cast<const Vec<V>*>(this);
return higher_vector_type(parN, this_vec[0]);
}
template <typename V>
auto Vec2Promotion<V, true>::xyn (const scalar_type& parN) const -> higher_vector_type {
auto& this_vec = *static_cast<const Vec<V>*>(this);
return higher_vector_type(this_vec[0], this_vec[1], parN);
} }
template <typename V> template <typename V>
@ -175,6 +187,18 @@ namespace vwr {
return higher_vector_type(this_vec[0], this_vec[1], this_vec[2], parW); return higher_vector_type(this_vec[0], this_vec[1], this_vec[2], parW);
} }
template <typename V>
auto VecAccessors<V, 1>::x() -> scalar_type& {
auto& this_vec = *static_cast<Vec<V>*>(this);
return this_vec[0];
}
template <typename V>
auto VecAccessors<V, 1>::x() const -> const scalar_type& {
const auto& this_vec = *static_cast<const Vec<V>*>(this);
return this_vec[0];
}
template <typename V> template <typename V>
auto VecAccessors<V, 2>::x() -> scalar_type& { auto VecAccessors<V, 2>::x() -> scalar_type& {
auto& this_vec = *static_cast<Vec<V>*>(this); auto& this_vec = *static_cast<Vec<V>*>(this);

View file

@ -7,5 +7,10 @@ TEST(vwr, conversion) {
{ {
svec1 s(10.0f); svec1 s(10.0f);
EXPECT_EQ(s.x(), 10.0f); EXPECT_EQ(s.x(), 10.0f);
auto s2 = s.x1();
static_assert(std::is_same<decltype(s2), svec2>::value, "Expecting svec2");
EXPECT_EQ(s2.x(), s.x());
EXPECT_EQ(s2.y(), 1.0f);
} }
} }