Commit 97ccb1d6 authored by Hans-Christian Ebke's avatar Hans-Christian Ebke
Browse files

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.
parent d85fe40f
......@@ -67,7 +67,6 @@
//== INCLUDES =================================================================
#include <OpenMesh/Core/System/config.h>
#include <ostream>
#include <cmath>
......@@ -78,6 +77,10 @@
#include <xmmintrin.h>
#endif
#ifdef CPP11_ENABLED
#include <array>
#include <initializer_list>
#endif
//== NAMESPACES ===============================================================
......@@ -98,22 +101,45 @@ namespace OpenMesh {
aligned, so that aligned SSE instructions can be used on these
vectors.
*/
template <typename Scalar,int N> struct VectorDataT
{
Scalar values_[N];
template<typename Scalar, int N> class VectorDataT {
public:
#ifdef CPP11_ENABLED
VectorDataT() {}
template<typename... T>
constexpr VectorDataT(T... vs) : values_ {vs...} {
static_assert(sizeof...(vs) == N,
"Incorrect number of vector components supplied.");
}
std::array<Scalar, N> values_;
#else
Scalar values_[N];
#endif
};
#if defined(__GNUC__) && defined(__SSE__)
/// This specialization enables us to use aligned SSE instructions.
template <> struct VectorDataT<float, 4>
{
union
{
__m128 m128;
float values_[4];
};
template<> class VectorDataT<float, 4> {
public:
#ifdef CPP11_ENABLED
VectorDataT() {}
template<typename... T>
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<float, 4> values_;
#else
float values_[4];
#endif
};
};
#endif
......
......@@ -97,6 +97,15 @@ public:
/// default constructor creates uninitialized values.
inline VectorT() {}
#ifdef CPP11_ENABLED
explicit inline VectorT(const Scalar& v) {
vectorize(v);
}
template<typename... T>
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));
......
......@@ -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
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment