Replace implementation of binary op assignments.

Use variadic templates instead of for loops. Add unit test.
This commit is contained in:
King_DuckZ 2017-01-27 19:02:52 +00:00
parent bbaabb695d
commit 48d7b5ddec
3 changed files with 41 additions and 12 deletions

View file

@ -169,6 +169,8 @@ namespace vwr {
private:
template <size_type... I, typename... Args>
void assign_values (const bt::number_seq<size_type, I...>&, Args... parArgs);
template <typename Op, typename V2, size_type... I>
void assign_values_op (Op parOp, const bt::number_seq<size_type, I...>& parSeq, const VecBase<V2>& parOther);
vector_type m_wrapped;
};

View file

@ -55,6 +55,12 @@ namespace vwr {
static_cast<void>(t);
}
template <typename V>
template <typename Op, typename V2, size_type... I>
void VecBase<V>::assign_values_op (Op parOp, const bt::number_seq<size_type, I...>& parSeq, const VecBase<V2>& parOther) {
this->assign_values(parSeq, parOp((*this)[I], parOther[I])...);
}
template <typename V>
auto VecBase<V>::operator[] (size_type parIndex) -> scalar_type& {
return VecGetter<V>::get_at(m_wrapped, parIndex);
@ -95,36 +101,28 @@ namespace vwr {
template <typename V2>
VecBase<V>& VecBase<V>::operator+= (const VecBase<V2>& parOther) {
static_assert(static_cast<int>(VectorWrapperInfo<V>::dimensions) == static_cast<int>(VectorWrapperInfo<V2>::dimensions), "Dimensions mismatch");
for (size_type z = 0; z < VectorWrapperInfo<V>::dimensions; ++z) {
(*this)[z] += parOther[z];
}
this->assign_values_op(std::plus<scalar_type>(), bt::number_range<size_type, 0, VectorWrapperInfo<V>::dimensions>(), parOther);
return *this;
}
template <typename V>
template <typename V2>
VecBase<V>& VecBase<V>::operator-= (const VecBase<V2>& parOther) {
static_assert(static_cast<int>(VectorWrapperInfo<V>::dimensions) == static_cast<int>(VectorWrapperInfo<V2>::dimensions), "Dimensions mismatch");
for (size_type z = 0; z < VectorWrapperInfo<V>::dimensions; ++z) {
(*this)[z] -= parOther[z];
}
this->assign_values_op(std::minus<scalar_type>(), bt::number_range<size_type, 0, VectorWrapperInfo<V>::dimensions>(), parOther);
return *this;
}
template <typename V>
template <typename V2>
VecBase<V>& VecBase<V>::operator*= (const VecBase<V2>& parOther) {
static_assert(static_cast<int>(VectorWrapperInfo<V>::dimensions) == static_cast<int>(VectorWrapperInfo<V2>::dimensions), "Dimensions mismatch");
for (size_type z = 0; z < VectorWrapperInfo<V>::dimensions; ++z) {
(*this)[z] *= parOther[z];
}
this->assign_values_op(std::multiplies<scalar_type>(), bt::number_range<size_type, 0, VectorWrapperInfo<V>::dimensions>(), parOther);
return *this;
}
template <typename V>
template <typename V2>
VecBase<V>& VecBase<V>::operator/= (const VecBase<V2>& parOther) {
static_assert(static_cast<int>(VectorWrapperInfo<V>::dimensions) == static_cast<int>(VectorWrapperInfo<V2>::dimensions), "Dimensions mismatch");
for (int z = 0; z < VectorWrapperInfo<V>::dimensions; ++z) {
(*this)[z] /= parOther[z];
}
this->assign_values_op(std::divides<scalar_type>(), bt::number_range<size_type, 0, VectorWrapperInfo<V>::dimensions>(), parOther);
return *this;
}

View file

@ -137,3 +137,32 @@ TEST(vwr, bin_operators_scalar) {
EXPECT_EQ(res, 1000 % a);
}
}
TEST(vwr, bin_assign_op) {
using namespace vwr;
{
ivec3 a(2, 4, 8);
ivec3 res(2 + 20, 4 + 20, 8 + 20);
a += ivec3(20);
EXPECT_EQ(res, a);
}
{
ivec3 a(2, 4, 8);
ivec3 res(2 - 20, 4 - 20, 8 - 20);
a -= ivec3(20);
EXPECT_EQ(res, a);
}
{
ivec3 a(2, 4, 8);
ivec3 res(2 * 20, 4 * 20, 8 * 20);
a *= ivec3(20);
EXPECT_EQ(res, a);
}
{
ivec3 a(2, 4, 8);
ivec3 res(2 / 2, 4 / 2, 8 / 2);
a /= ivec3(2);
EXPECT_EQ(res, a);
}
}