From 97ccb1d641176dabd83d92be2d3a2a7056615db1 Mon Sep 17 00:00:00 2001 From: Hans-Christian Ebke Date: Mon, 9 Nov 2015 18:46:39 +0100 Subject: [PATCH] Modernized VectorT constructors in C++11 branch. * Less redundancy. * We can now make some of the VectorT constructors constexpr which is useful for other features. --- src/OpenMesh/Core/Geometry/VectorT.hh | 48 +++++++++++++++++------ src/OpenMesh/Core/Geometry/VectorT_inc.hh | 13 +++++- src/Unittests/unittests_vector_type.cc | 28 +++++++++++++ 3 files changed, 77 insertions(+), 12 deletions(-) diff --git a/src/OpenMesh/Core/Geometry/VectorT.hh b/src/OpenMesh/Core/Geometry/VectorT.hh index 5b552072..9c3db706 100644 --- a/src/OpenMesh/Core/Geometry/VectorT.hh +++ b/src/OpenMesh/Core/Geometry/VectorT.hh @@ -67,7 +67,6 @@ //== INCLUDES ================================================================= - #include #include #include @@ -78,6 +77,10 @@ #include #endif +#ifdef CPP11_ENABLED +#include +#include +#endif //== NAMESPACES =============================================================== @@ -98,22 +101,45 @@ namespace OpenMesh { aligned, so that aligned SSE instructions can be used on these vectors. */ -template struct VectorDataT -{ - Scalar values_[N]; +template class VectorDataT { + public: +#ifdef CPP11_ENABLED + VectorDataT() {} + + template + constexpr VectorDataT(T... vs) : values_ {vs...} { + static_assert(sizeof...(vs) == N, + "Incorrect number of vector components supplied."); + } + std::array values_; +#else + Scalar values_[N]; +#endif }; #if defined(__GNUC__) && defined(__SSE__) /// This specialization enables us to use aligned SSE instructions. -template <> struct VectorDataT -{ - union - { - __m128 m128; - float values_[4]; - }; +template<> class VectorDataT { + public: +#ifdef CPP11_ENABLED + VectorDataT() {} + + template + constexpr VectorDataT(T... vs) : values_ {vs...} { + static_assert(sizeof...(vs) == 4, + "Incorrect number of vector components supplied."); + } +#endif + union { + __m128 m128; +#ifdef CPP11_ENABLED + std::array values_; +#else + float values_[4]; +#endif + }; }; #endif diff --git a/src/OpenMesh/Core/Geometry/VectorT_inc.hh b/src/OpenMesh/Core/Geometry/VectorT_inc.hh index e76ca544..b0c682e8 100644 --- a/src/OpenMesh/Core/Geometry/VectorT_inc.hh +++ b/src/OpenMesh/Core/Geometry/VectorT_inc.hh @@ -97,6 +97,15 @@ public: /// default constructor creates uninitialized values. inline VectorT() {} +#ifdef CPP11_ENABLED + explicit inline VectorT(const Scalar& v) { + vectorize(v); + } + + template + constexpr VectorT(T... vs) : Base {vs...} + { } +#else /// special constructor for 1D vectors explicit inline VectorT(const Scalar& v) { // assert(DIM==1); @@ -124,6 +133,8 @@ public: const Scalar v2, const Scalar v3) { Base::values_[0]=v0; Base::values_[1]=v1; Base::values_[2]=v2; Base::values_[3]=v3; } + + VectorT homogenized() { return VectorT(Base::values_[0]/Base::values_[3], Base::values_[1]/Base::values_[3], Base::values_[2]/Base::values_[3], 1); } #endif #if DIM == 5 @@ -142,7 +153,7 @@ public: Base::values_[3]=v3; Base::values_[4]=v4; Base::values_[5]=v5; } #endif - +#endif /// construct from a value array (explicit) explicit inline VectorT(const Scalar _values[DIM]) { memcpy(Base::values_, _values, DIM*sizeof(Scalar)); diff --git a/src/Unittests/unittests_vector_type.cc b/src/Unittests/unittests_vector_type.cc index 240eab07..0d157766 100644 --- a/src/Unittests/unittests_vector_type.cc +++ b/src/Unittests/unittests_vector_type.cc @@ -83,6 +83,34 @@ TEST_F(OpenMeshVectorTest, VectorCasting) { } +#ifdef CPP11_ENABLED +TEST_F(OpenMeshVectorTest, cpp11_constructors) { + OpenMesh::Vec3d vec1 { 1.2, 2.0, 3.0 }; + EXPECT_EQ(1.2, vec1[0]); + EXPECT_EQ(2.0, vec1[1]); + EXPECT_EQ(3.0, vec1[2]); + + OpenMesh::Vec4f vec2 { 1.2f, 3.5f, 1.0f, 0.0f }; + + EXPECT_EQ(1.2f, vec2[0]); + EXPECT_EQ(3.5f, vec2[1]); + EXPECT_EQ(1.0f, vec2[2]); + EXPECT_EQ(0.0f, vec2[3]); + + OpenMesh::Vec4f vec2b { vec2 }; + + EXPECT_EQ(1.2f, vec2b[0]); + EXPECT_EQ(3.5f, vec2b[1]); + EXPECT_EQ(1.0f, vec2b[2]); + EXPECT_EQ(0.0f, vec2b[3]); + + OpenMesh::Vec4d vec4d { 1.23 }; + EXPECT_EQ(1.23, vec4d[0]); + EXPECT_EQ(1.23, vec4d[1]); + EXPECT_EQ(1.23, vec4d[2]); + EXPECT_EQ(1.23, vec4d[3]); +} +#endif }