X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Flinal%2Fvector.h;h=610ac2103a21ab83e0b58f88905e6d07c6962d2d;hb=291c11cf66e7083dc21fffea1afbdeaaad96077d;hp=6dfe6ca0167fb3e1d57e65217003e3d700f6a3b3;hpb=ffb043ce670d733decc03c6e4240a4e6d980caec;p=libs%2Fmath.git diff --git a/source/linal/vector.h b/source/linal/vector.h index 6dfe6ca..610ac21 100644 --- a/source/linal/vector.h +++ b/source/linal/vector.h @@ -3,6 +3,7 @@ #include #include +#include namespace Msp { namespace LinAl { @@ -74,14 +75,23 @@ template class Vector: public VectorComponents { public: + typedef T ElementType; + Vector(); Vector(const T *); - Vector(T, T); - Vector(T, T, T); - Vector(T, T, T, T); + + /** Constructs a vector from an array of interleaved values. Intended for + use by Matrix row accessor. */ + Vector(const T *, unsigned); + + template + Vector(T, Args...); + template Vector(const Vector &); + unsigned size() const { return N; } + template Vector slice(unsigned) const; @@ -109,30 +119,22 @@ inline Vector::Vector(const T *d) (*this)[i] = d[i]; } -/* The compiler won't instantiate these unless they are used. Trying to use -them on the wrong class results in an error. */ -template -inline Vector::Vector(T x_, T y_) -{ - this->VectorComponents::x = x_; - this->VectorComponents::y = y_; -} - template -inline Vector::Vector(T x_, T y_, T z_) +inline Vector::Vector(const T *d, unsigned stride) { - this->VectorComponents::x = x_; - this->VectorComponents::y = y_; - this->VectorComponents::z = z_; + for(unsigned i=0; i -inline Vector::Vector(T x_, T y_, T z_, T w_) -{ - this->VectorComponents::x = x_; - this->VectorComponents::y = y_; - this->VectorComponents::z = z_; - this->VectorComponents::w = w_; +template +inline Vector::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 { static_cast(v)... }) + (*this)[i++] = c; } template @@ -157,9 +159,9 @@ template inline Vector compose(T s, const Vector &v) { Vector r; + r[0] = s; for(unsigned i=0; i cross(const Vector &v1, const Vector &v2) return Vector(v1.y*v2.z-v1.z*v2.y, v1.z*v2.x-v1.x*v2.z, v1.x*v2.y-v1.y*v2.x); } +template +inline std::ostream &operator<<(std::ostream &s, const Vector &v) +{ + s << "Vector" << N << '('; + for(unsigned i=0; i