Boost logo

Boost :

From: Ben FrantzDale (benfrantzdale_at_[hidden])
Date: 2007-03-07 12:54:15


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_at_[hidden]> 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
>


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk