
Kasak, Yes! This is something I've wanted for some time. Some thoughts: * Default to value_type=double so "vector3" Just Works. * It would be good to focus on Concepts so that an n-dimensional vector could be used with other templated linear algebra stuff, including uBlas. * A vector should have a data() method or a data(v) friend function to give access to its internal representation, e.g., for passing it directly to OpenGL. Then I could call glVertex3f(data(v)). * It should be safe to cast a C-style array to a vector, so I could have void old_function(double* vec3) { vector3& v = some_kind_of_cast<vector3&>(vec3); new_function(v); } * Make sure it would be easy to add fourth-order tensors (linear transformations for 3x3 matrices). In computational mechanics those get used a lot. But yes, this is desperately needed in computer graphics and in computational mechanics. I my experience TVMET's behavior (like lack of a regular copy constructor, I think) make for too steep a learning curve. —Ben On 3/4/07, Kasak Sergey <tiger_trader@mail.ru> wrote:
library contain vector(any static size), matrix 4x4, quaternion, plane(3D), sphere(3D), AABB(3D) and have little fuzzy logic support. This is little code snippet of vector class: ... template < typename T, IT N, template<class> class IPolicy > class Vector : private IPolicy<T> { public: typedef Vector<T, N, IPolicy> VectorType; typedef T value_type; typedef T* iterator; typedef const T* const_iterator; public: Vector() { IPolicy<T>::construct<N>( _a ); }
// copy constructor & assigment operator are fine // (hold objects by value)
template<IT M> explicit Vector( const Vector<T, M>& rhs ) { enum { copy_sz = smin<M, N>::result }; std::copy(rhs._a, rhs._a + copy_sz, _a); IPolicy<T>::construct<N - copy_sz>( _a + copy_sz ); }
explicit Vector( const T& val ) { nInternal::for_each_set<T, N>::Do(_a, val); }
Vector ( const T& x, const T& y, typename boost::enable_if_c<(N == 2)> * = 0 ) { _a[0] = x; _a[1] = y; }
Vector ( const T& x, const T& y, const T& z, typename boost::enable_if_c<(N == 3)> * = 0 ) { _a[0] = x; _a[1] = y; _a[2] = z; }
Vector ( const T& x, const T& y, const T& z, const T& w, typename boost::enable_if_c<(N == 4)> * = 0 ) { _a[0] = x; _a[1] = y; _a[2] = z; _a[3] = w; }
template<IT M> explicit Vector( const T (&arg)[M] ) { enum { copy_sz = smin<M, N>::result }; std::copy(arg, arg + copy_sz, _a); IPolicy<T>::construct<N - copy_sz>( _a + copy_sz ); }
template<IT M> Vector& operator = ( const T (&arg)[M] ) { enum { copy_sz = smin<M, N>::result }; std::copy(arg, arg + copy_sz, _a); IPolicy<T>::construct<N - copy_sz>( _a + copy_sz ); return *this; }
template<IT M> Vector& operator = ( const Vector<T, M>& rhs ) { return operator = ( rhs._a ); }
Vector& operator = ( const T& val ) { Fill(val); return *this; }
T& operator [] ( IT idx ) { return _a[idx]; }
T& at( IT idx ) { if( idx < N ) return _a[idx];
throw std::out_of_range(typeid(*this).name()); }
template<IT I> T& at_c() { BOOST_STATIC_ASSERT( I < N ); return _a[I]; }
const T& operator [] ( IT idx ) const { return const_cast<VectorType*>(this)->operator [](idx); }
const T& at( IT idx ) const { return const_cast<VectorType*>(this)->at(idx); }
template<IT I> const T& at_c() const { return const_cast<VectorType*>(this)->at_c<I>(); }
const_iterator begin() const { return &_a[0]; } iterator begin() { return &_a[0]; }
const_iterator end() const { return &_a[N]; } iterator end() { return &_a[N]; }
template<template<class> class IP> operator Vector<T, N, IP>& () { return reinterpret_cast<Vector<T, N, IP>&>(*this); }
T& x( typename boost::enable_if_c<(N > 0)> * = 0 ) { return _a[0]; }
T& y( typename boost::enable_if_c<(N > 1)> * = 0 ) { return _a[1]; }
T& z( typename boost::enable_if_c<(N > 2)> * = 0 ) { return _a[2]; }
T& w( typename boost::enable_if_c<(N > 3)> * = 0 ) { return _a[3]; }
Vector operator - () const { Vector ret; nInternal::neg_op<T, N>::Do(_a, ret._a); return ret; }
bool IsEqual( const VectorType& vec, const T& accuracy ) const { return nInternal::cmp_op<T, N>::Do ( _a, vec._a, nInternal::not_near<T>(accuracy) ); }
bool operator == ( const VectorType& vec ) const { return nInternal::cmp_op<T, N>::Do(_a, vec._a, std::not_equal_to<T>()); }
bool operator != ( const VectorType& vec ) const { return nInternal::cmp_op<T, N>::Do(_a, vec._a, std::equal_to<T>()); }
bool operator < ( const VectorType& vec ) const { return nInternal::cmp_op<T, N>::Do ( _a, vec._a, std::not2(std::less<T>()) ); }
Vector& operator += ( const VectorType& other ) { nInternal::bin_op<T, N>::Do ( _a, _a, other._a, std::plus<T>() ); return *this; }
Vector& operator -= ( const VectorType& other ) { nInternal::bin_op<T, N>::Do ( _a, _a, other._a, std::minus<T>() ); return *this; }
Vector& operator *= ( const VectorType& other ) { nInternal::bin_op<T, N>::Do ( _a, _a, other._a, std::multiplies<T>() ); return *this; }
Vector& operator /= ( const VectorType& other ) { nInternal::bin_op<T, N>::Do ( _a, _a, other._a, std::divides<T>() ); return *this; } ... };
Little sample: Vector<3, float> v0(0.f, 1.f, 2.f), v1(1.f), v2(v0 + v1); float _x = v0.x(), _x0 = v0[0], _x1 = v0.at(-1);
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost