#include #include #include #include #include #include #include #include namespace rci { namespace cartesian { struct uninitialized_t { }; static const uninitialized_t uninitialized = { }; template class vector { public: static const int dim = Dim; typedef Rep rep; boost::array coord; vector(uninitialized_t) { } vector() { coord.fill(rep()); } vector(const vector& v) : coord(v.coord) { } vector& operator=(const vector& v) { coord = v.coord; return *this; } template vector(const vector& v) { coord = v.coord; } template vector& operator=(const vector& v) { for (int i = 0; i != dim; ++i) coord[i] = v.coord[i]; return *this; } template vector(InIter first_, InIter last_) { using namespace std; if (distance(first_, last_) != dim) { std::out_of_range e("cartesian::vector<> invalid input iterators"); boost::throw_exception(e); } copy(first_, last_, coord.begin()); } // iterator initialization template const rep& get() const { return coord[N]; } template rep& get() { return coord[N]; } template void set(rep v) { coord[N] = v; } rep& operator[](int i) { return coord[i]; } const rep& operator[](int i) const { return coord[i]; } vector operator+() const { return vector(*this); } vector operator-() const { vector rval(uninitialized); for (int i=0; i!=dim; ++i) rval.coord[i] = -coord[i]; return rval; } template vector& operator+=(const vector& rhs) { for (int i=0; i!=dim; ++i) coord[i] += rhs[i]; return *this; } template vector& operator-=(const vector& rhs) { for (int i=0; i!=dim; ++i) coord[i] -= rhs[i]; return *this; } template vector& operator*=(const U& rhs) { for (int i=0; i!=dim; ++i) coord[i] *= rhs; return *this; } template vector& operator/=(const U& rhs) { for (int i=0; i!=dim; ++i) coord[i] /= rhs; return *this; } }; // vector template Rep& get(vector& v) { return v.get(); } template const Rep& get(const vector& v) { return v.get(); } template void set(vector& v, Rep x) { return v.set(x); } } } // rci::cartesian #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() BOOST_TYPEOF_REGISTER_TEMPLATE(rci::cartesian::vector, (int)(class)) namespace rci { namespace cartesian { template inline typename boost::units::multiply_typeof_helper::type abs_squared(const vector& v) { typedef typename boost::units::multiply_typeof_helper::type result_type; result_type result = result_type(); for (int i=0; i!=Dim; ++i) { const Rep& x = v[i]; result += x * x; } return result; } // abs_squared template inline Rep abs(const vector& v) { using namespace std; return sqrt(abs_squared(v)); } // abs // vector + vector template inline typename boost::units::add_typeof_helper< vector, vector >::type operator+(const vector&lhs, const vector& rhs) { typedef typename boost::units::add_typeof_helper< vector, vector >::type result_type; result_type result(uninitialized); for (int i=0; i!=Dim; ++i) result[i] = lhs[i] + rhs[i]; return result; } // vector - vector template inline typename boost::units::subtract_typeof_helper< vector, vector >::type operator-(const vector&lhs, const vector& rhs) { typedef typename boost::units::subtract_typeof_helper< vector, vector >::type result_type; result_type result(uninitialized); for (int i=0; i!=Dim; ++i) result[i] = lhs[i] - rhs[i]; return result; } // T * vector template inline typename boost::units::multiply_typeof_helper >::type operator*(const T1& lhs, const vector&rhs) { typedef typename boost::units::multiply_typeof_helper< T1, vector >::type result_type; result_type result(uninitialized); for (int i=0; i!=Dim; ++i) result[i] = lhs * rhs[i]; return result; } // vector * T template inline typename boost::units::multiply_typeof_helper >::type operator*(const vector&lhs, const T2& rhs) { return rhs * lhs; } // vector / T template inline typename boost::units::divide_typeof_helper, T2>::type operator/(const vector&lhs, const T2& rhs) { typedef typename boost::units::divide_typeof_helper, T2>::type result_type; result_type result(uninitialized); for (int i=0; i!=Dim; ++i) result[i] = lhs[i] / rhs; return result; } // vector * vector template inline typename boost::units::multiply_typeof_helper< vector, vector >::type operator*(const vector& lhs, const vector& rhs) { typename boost::units::multiply_typeof_helper< vector, vector >::type result_type; result_type result = result_type(); for (int i=0; i!=Dim; ++i) result += lhs[i] * rhs[i]; return result; } // dot product // vector == vector template inline bool operator==(const vector& lhs, const vector& rhs) { for (int i=0; i!=Dim; ++i) { if (lhs[i] != rhs[i]) return false; } return true; } // vector != vector template inline bool operator!=(const vector& lhs, const vector& rhs) { return !(lhs == rhs); } template inline std::basic_ostream& operator<<(std::basic_ostream& os, const vector& v) { os << '<' << v[0]; for (int i=1; i!=Dim; ++i) os << ' ' << v[i]; return os << '>'; } // << vector } } // rci::cartesian #include #include #include using namespace std; using namespace boost; using namespace boost::units; using namespace rci; using namespace rci::cartesian; int main() { cartesian::vector<3, double> v; v[0] = 1.0; v[1] = 2.0; v[2] = 3.0; cout << v << endl; cartesian::vector<3, quantity > w; quantity factor = 1.0 * si::meter; w = v * factor; cout << w << endl; } // main