]> git.tdb.fi Git - libs/math.git/commitdiff
Improve Vector constructor for C++11
authorMikko Rasa <tdb@tdb.fi>
Sun, 2 Jun 2019 12:28:34 +0000 (15:28 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sun, 2 Jun 2019 16:13:09 +0000 (19:13 +0300)
The new overload allows vectors of any size to be constructed by passing
the component values as constructor arguments.

source/linal/vector.h
tests/vector.cpp

index 767cc88da2d5b5518adc72b00d5f7f55582f8963..31597d4282410e2606590eaea2faa6d3c22c2cd9 100644 (file)
@@ -84,9 +84,14 @@ public:
        use by Matrix row accessor. */
        Vector(const T *, unsigned);
 
+#if __cplusplus >= 201103L
+       template<typename... Args>
+       Vector(T, Args...);
+#else
        Vector(T, T);
        Vector(T, T, T);
        Vector(T, T, T, T);
+#endif
        template<typename U>
        Vector(const Vector<U, N> &);
 
@@ -126,6 +131,18 @@ inline Vector<T, N>::Vector(const T *d, unsigned stride)
                (*this)[i] = d[i*stride];
 }
 
+#if __cplusplus >= 201103L
+template<typename T, unsigned N>
+template<typename... Args>
+inline Vector<T, N>::Vector(T x_, Args... v)
+{
+       static_assert(1+sizeof...(v)==N, "Incorrect number of arguments in Vector constructor");
+       (*this)[0] = x_;
+       unsigned i = 1;
+       for(auto c: std::initializer_list<T> { static_cast<T>(v)... })
+               (*this)[i++] = c;
+}
+#else
 /* The compiler won't instantiate these unless they are used.  Trying to use
 them on the wrong class results in an error. */
 template<typename T, unsigned N>
@@ -151,6 +168,7 @@ inline Vector<T, N>::Vector(T x_, T y_, T z_, T w_)
        this->VectorComponents<T, 4>::z = z_;
        this->VectorComponents<T, 4>::w = w_;
 }
+#endif
 
 template<typename T, unsigned N>
 template<typename U>
index 14aea8708095b5df6dd358331a6f01c39560843d..cf07329cd1fa25368d6f0998431b08c8650c878d 100644 (file)
@@ -18,6 +18,7 @@ public:
        static const char *get_name() { return "Vector"; }
 
 private:
+       void constructors();
        void component_aliases();
        void composition();
        void slice();
@@ -30,6 +31,7 @@ private:
 
 VectorTests::VectorTests()
 {
+       add(&VectorTests::constructors, "Constructors");
        add(&VectorTests::component_aliases, "Component aliases");
        add(&VectorTests::composition, "Compose");
        add(&VectorTests::slice, "Slice");
@@ -40,6 +42,29 @@ VectorTests::VectorTests()
        add(&VectorTests::unit_vec, "Normalize");
 }
 
+void VectorTests::constructors()
+{
+       static int data[] = { 1, 2, 3 };
+
+       Vector2i v1(1, 2);
+       EXPECT_EQUAL(v1[0], 1);
+       EXPECT_EQUAL(v1[1], 2);
+
+       Vector3i v2(data);
+       EXPECT_EQUAL(v2[0], 1);
+       EXPECT_EQUAL(v2[1], 2);
+       EXPECT_EQUAL(v2[2], 3);
+
+#if __cplusplus >= 201103L
+       LinAl::Vector<int, 1> v3(1);
+       EXPECT_EQUAL(v3[0], 1);
+
+       LinAl::Vector<int, 5> v4(1, 2, 3, 4, 5);
+       EXPECT_EQUAL(v4[0], 1);
+       EXPECT_EQUAL(v4[4], 5);
+#endif
+}
+
 void VectorTests::component_aliases()
 {
        Vector3i v;