I've been working on a 3D mathematical vector class which should be as streamlined as possible for use in numerical simulations. It will be used to model 3D-physical vectors.
Here, 3D-vector should be taken in mathematical sense, meaning a tuple (a,b,c).
I hoped to design it in a modern and fast way - but one is never perfect. So, I would be interested in some input from your side. Any tips for making this faster?
//threevector.h
#ifndef threevector_h_
#define threevector_h_
#include <fstream>
#include <cmath>
#include <array>
template <class T>
class threevector
{
private:
static const int dim = 3; //dimension of vector
std::array<T,dim> container;
public:
//constructors and assignment
threevector(const double a = 0, const double b = 0, const double c = 0):
container({{a,b,c}}) {}; //standard constructor
threevector(const threevector& a): container(a.container) {};
//copy constructor
// add once gcc 4.7 is used
// threevector(threevector&& other): threevector() {swap(*this, other);}
// move constructor
threevector& operator=(threevector rhs) //assignment
{
swap(*this, rhs);
return *this;
}
void swap(threevector& first, threevector& second)
{first.container.swap(second.container);}
//operators
threevector& operator+=(const threevector& rhs)
{
container[0] += rhs.container[0];
container[1] += rhs.container[1];
container[2] += rhs.container[2];
return *this;
}
threevector& operator-=(const threevector& rhs)
{
*this += -rhs;
return *this;
}
threevector& operator*=(const double rhs) //scalar multiplication assignment
{
container[0] *= rhs;
container[1] *= rhs;
container[2] *= rhs;
return *this;
}
threevector& operator/=(const double rhs) //scalar division assignment
{
*this *= 1./rhs;
return *this;
}
threevector operator+() const //unary plus
{
threevector a(*this);
return a;
}
threevector operator-() const //unary minus
{
threevector a(*this);
a *= -1;
return a;
}
T& operator[](const int input) {return container[input];} //access operator
const T& operator[](const int input) const {return container[input];}
// const access operator
//utility functions
double abs() const
{return sqrt(container[0]*container[0]+container[1]*container[1]+
container[2]*container[2]);}
double abs_sq() const {return pow(abs(),2);}
void reset() { container[0] = 0; container[1] = 0; container[2] = 0;}
};
//output operator
template<class T>
std::ostream& operator<<(std::ostream& os, const threevector<T>& obj)
{
os << std::fixed << "(" << obj[0] << "," << obj[1] << "," << obj[2] << ")";
return os;
}
//addition operator
template<class T>
inline threevector<T> operator+(threevector<T> lhs, const threevector<T>& rhs)
{
lhs += rhs;
return lhs;
}
//subtraction operator
template<class T>
inline threevector<T> operator-(threevector<T> lhs, const threevector<T>& rhs)
{
lhs -= rhs;
return lhs;
}
//scalar product
template<class T>
inline double operator*(const threevector<T>& lhs, const threevector<T>& rhs)
{return lhs[0] * rhs[0] + lhs[1] * rhs[1] + lhs[2] * rhs[2];}
//product with scalar
template<class T>
inline threevector<T> operator*(const double lhs, threevector<T> rhs)
{
rhs[0] *= lhs;
rhs[1] *= lhs;
rhs[2] *= lhs;
return rhs;
}
//product with scalar
template<class T>
inline threevector<T> operator*(threevector<T> lhs, const double rhs){return rhs*lhs;}
// scalar division
template<class T>
inline threevector<T> operator/(threevector<T> lhs, const double rhs){return lhs*(1./rhs);};
#endif