usata-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Usata-commits] Changes to usata2/src/math/vector-template.hpp


From: Chong Kai Xiong
Subject: [Usata-commits] Changes to usata2/src/math/vector-template.hpp
Date: Sat, 22 Jan 2005 05:02:14 -0500

Index: usata2/src/math/vector-template.hpp
diff -u usata2/src/math/vector-template.hpp:1.1 
usata2/src/math/vector-template.hpp:1.2
--- usata2/src/math/vector-template.hpp:1.1     Mon Jan 10 08:14:52 2005
+++ usata2/src/math/vector-template.hpp Sat Jan 22 10:02:10 2005
@@ -9,46 +9,91 @@
 // included in the software distribution, or visit
 // http://www.fsf.org/licenses/gpl.html.
 //
-// $Id: vector-template.hpp,v 1.1 2005/01/10 08:14:52 Descender Exp $
+// $Id: vector-template.hpp,v 1.2 2005/01/22 10:02:10 Descender Exp $
 
 #ifndef USATA_VECTOR_TEMPLATE_HPP
 #define USATA_VECTOR_TEMPLATE_HPP
 
+#include <boost/format.hpp>
+#include <boost/concept_check.hpp>
+
 namespace usata
 {
        namespace math
        {
+
+               // NOTE: I'm somewhat forced to define operator function
+               // parameter type for VectorUnaryOp and VectorBinaryOp as a
+               // class instead of template function references because GCC
+               // <= 4.0 throws an ICE in our face - descender
+
+               template <typename T>
                class Scalar;
 
+               template <typename T, int N>
+               class Array;
+
+               template <typename T, typename ReprT = Array<T, 4> >
                class Vector;
 
-               template <typename A, typename B, typename BinaryOp>
+               template <typename T, typename A, typename UnaryOp>
+               class VectorUnaryOp;
+
+               template <typename T, typename A, typename B, typename BinaryOp>
                class VectorBinaryOp;
 
+               // convenient typedefs
+
+               typedef Vector<int>    Vector4i;
+               typedef Vector<float>  Vector4f;
+               typedef Vector<double> Vector4d;
+
+
+               // concepts
+
+               template <typename T>
+               struct IsNumericConcept
+               {
+                       void
+                       constraints()
+                       {
+                               
boost::function_requires<boost::ComparableConcept<T> >();
+
+                               T a, b, c;
+                               c = a + b;
+                               c = a - b;
+                               c = a * b;
+                               c = a / b;
+                               c = -a;
+                       }
+               };
+
+
+               // Operand copying semantics 
+
                template <typename T>
                struct OperandTraits
-               {        
+               {
                        typedef const T& Ref;
                };
 
-               template <>
-               struct OperandTraits<Scalar>
+               template <typename T>
+               struct OperandTraits<Scalar<T> >
                {
-                       typedef Scalar Ref;
+                       typedef Scalar<T> Ref;
                };
 
+
+               template <typename T>
                class Scalar
                {
                public:
 
-                       Scalar(int x)
+                       explicit Scalar(T x)
                                : m_x(x)
                        {}
 
-                       ~Scalar()
-                       {}
-
-                       int
+                       T
                        operator [] (int index) const
                        {
                                return m_x;
@@ -56,44 +101,90 @@
 
                private:
 
-                       int m_x;
+                       T m_x;
+               };
+
+
+               template <typename T, int N>
+               class Array
+               {
+               public:
+
+                       T
+                       operator [] (int index) const
+                       {
+                               return m_elements[index];
+                       }
+
+                       T&
+                       operator [] (int index)
+                       {
+                               return m_elements[index];
+                       }
+
+               private:
+
+                       T m_elements[N];
                };
 
-               class Vector 
+
+               template <typename T, typename ReprT>
+               class Vector
                {
                public:
+                       BOOST_CLASS_REQUIRE(T, usata::math, IsNumericConcept);
 
-                       Vector(int x = 0, int y = 0, int z = 0, int w = 0)
+                       Vector(T x = 0, T y = 0, T z = 0, T w = 0)
                        {
-                               v[0] = x;
-                               v[1] = y;
-                               v[2] = z;
-                               v[3] = w;
+                               m_repr[0] = x;
+                               m_repr[1] = y;
+                               m_repr[2] = z;
+                               m_repr[3] = w;
                        }
-          
-                       template <typename T>
+
+                       // NOTE: GCC (and probably other compilers) can't 
optimize
+                       // this call away - descender
+                       Vector(const ReprT& repr)
+                               : m_repr(repr)
+                       {}
+
+                       template <typename ReprT2>
                        Vector&
-                       operator = (const T& expr)
+                       operator = (const Vector<T, ReprT2>& rhs)
                        {
-                               v[0] = expr[0];
-                               v[1] = expr[1];
-                               v[2] = expr[2];
-                               v[3] = expr[3];
+                               m_repr[0] = rhs[0];
+                               m_repr[1] = rhs[1];
+                               m_repr[2] = rhs[2];
+                               m_repr[3] = rhs[3];
                                return *this;
                        }
 
+                       ReprT&
+                       repr() 
+                       {
+                               T x;
+                               return x.cannot_be_used_as_lvalue_error();
+                       }
+
+                       // rvalue
+                       const ReprT&
+                       repr() const
+                       {
+                               return m_repr;
+                       }
+
                        // lvalue 
-                       int&
+                       T&
                        operator [] (int index)
                        {
-                               return v[index];
+                               return m_repr[index];
                        }
 
                        // rvalue
-                       int
+                       T
                        operator [] (int index) const
                        {
-                               return v[index];
+                               return m_repr[index];
                        }
 
                        friend std::ostream&
@@ -101,50 +192,66 @@
                        {
                                return out << boost::format("[%1% %2% %3% 
%4%]") 
                                        % v[0] % v[1] % v[2] % v[3];
-
                        }
 
                private:
 
-                       int v[4];
+                       ReprT m_repr;
                };
 
-               template <typename A, typename UnaryOp>
+
+               template <typename T, typename A, typename UnaryOp>
                class VectorUnaryOp
                {
                public:
+                       BOOST_CLASS_REQUIRE(T, usata::math, IsNumericConcept);
 
                        VectorUnaryOp(const A& a)
                                : m_a(a)
                        {}
 
-                       int
+                       T
                        operator [] (int index) const
                        {
                                return UnaryOp::eval(m_a[index]);
                        }
 
+                       T&
+                       operator [] (int index)
+                       {
+                               T x;
+                               return x.cannot_be_used_as_lvalue_error();
+                       }
+
                private:
 
                        typename OperandTraits<A>::Ref m_a;
                };
 
-               template <typename A, typename B, typename BinaryOp>
+               template <typename T, typename A, typename B, typename BinaryOp>
                class VectorBinaryOp 
                {
                public:
+                       BOOST_CLASS_REQUIRE(T, usata::math, isNumericConcept);
 
                        VectorBinaryOp(const A& a, const B& b)
                                : m_a(a),
                                  m_b(b)
                        {}
 
-                       int
+                       T
                        operator [] (int index) const
                        {
                                return BinaryOp::eval(m_a[index], m_b[index]);
                        }
 
+                       T&
+                       operator [] (int index)
+                       {
+                               T x;
+                               return x.cannot_be_used_as_lvalue_error();
+                       }
+
                private:
 
                        typename OperandTraits<A>::Ref m_a;
@@ -152,94 +259,175 @@
                };
 
 
-               struct plus     { static int eval(int a, int b) { return a + b; 
} };
-               struct minus    { static int eval(int a, int b) { return a - b; 
} };
-               struct multiply { static int eval(int a, int b) { return a * b; 
} };
-               struct divide   { static int eval(int a, int b) { return a / b; 
} };
-               struct negate   { static int eval(int a)        { return -a;    
} };
-
-               // template typedefs
-
-               template <typename A, typename B>
-               struct VectorPlus     { typedef VectorBinaryOp<A, B, plus> 
type; };
-
-               template <typename A, typename B>
-               struct VectorMinus    { typedef VectorBinaryOp<A, B, minus> 
type; };
-
-               template <typename A, typename B>
-               struct VectorMultiply { typedef VectorBinaryOp<A, B, multiply> 
type; };
-
-               template <typename A, typename B>
-               struct VectorDivide   { typedef VectorBinaryOp<A, B, divide> 
type; };
-
-               template <typename A>
-               struct VectorNegate   { typedef VectorUnaryOp<A, negate> type; 
};
-
-               // operators
-
-               template <typename A, typename B>
-               typename VectorPlus<A, B>::type 
-               operator + (const A& a, const B& b)
+               template <typename T>
+               struct Plus
                {
-                       typedef typename VectorPlus<A,B>::type PlusResult;
-                       return PlusResult(a, b);
-               }
+                       static T
+                       eval(T a, T b)
+                       {
+                               return a + b;
+                       }
+               };
 
-               template <typename A, typename B>
-               typename VectorMinus<A, B>::type 
-               operator - (const A& a, const B& b)
+               template <typename T>
+               struct Minus
                {
-                       typedef typename VectorMinus<A,B>::type MinusResult;
-                       return MinusResult(a, b);
-               }
+                       static T
+                       eval(T a, T b)
+                       {
+                               return a - b;
+                       }
+               };
 
-               template <typename A>
-               typename VectorNegate<A>::type
-               operator - (const A& a)
+               template <typename T>
+               struct Multiply
                {
-                       typedef typename VectorNegate<A>::type NegateResult;
-                       return NegateResult(a);
-               }
+                       static T
+                       eval(T a, T b) 
+                       {
+                               return a * b;
+                       }
+               };
+                       
+               template <typename T>
+               struct Divide
+               {
+                       static T
+                       eval(T a, T b)
+                       {
+                               return a / b;
+                       }
+               };
 
-               template <typename A, typename B>
-               typename VectorMultiply<A, B>::type 
-               operator * (const A& a, const B& b)
+               template <typename T>
+               struct Negate
                {
-                       typedef typename VectorMultiply<A,B>::type 
MultiplyResult;
-                       return MultiplyResult(a, b);
-               }
+                       static T
+                       eval(T a)
+                       {
+                               return -a;
+                       }
+               };
+               
+               template <typename T, typename A, typename B>
+               struct VectorPlus
+               {
+                       typedef VectorBinaryOp<T, A, B, Plus<T> > Repr;
+                       typedef Vector<T, Repr> Vector;
+               };
 
-               template <typename A>
-               typename VectorMultiply<A, Scalar>::type 
-               operator * (const A& a, int b)
+               template <typename T, typename A, typename B>
+               struct VectorMinus
                {
-                       typedef typename VectorMultiply<A, Scalar>::type 
MultiplyResult;
-                       return MultiplyResult(a, Scalar(b));
-               }
+                       typedef VectorBinaryOp<T, A, B, Minus<T> > Repr;
+                       typedef Vector<T, Repr> Vector;
+               };
 
-               template <typename B>
-               typename VectorMultiply<Scalar, B>::type 
-               operator * (int a, const B& b)
+               template <typename T, typename A, typename B>
+               struct VectorMultiply
                {
-                       typedef typename VectorMultiply<Scalar, B>::type 
MultiplyResult;
-                       return MultiplyResult(Scalar(a), b);
-               }
+                       typedef VectorBinaryOp<T, A, B, Multiply<T> > Repr;
+                       typedef Vector<T, Repr> Vector;
+               };
 
-               template <typename A, typename B>
-               typename VectorDivide<A, B>::type 
-               operator / (const A& a, const B& b)
+               template <typename T, typename A, typename B>
+               struct VectorDivide
                {
-                       typedef typename VectorDivide<A,B>::type DivideResult;
-                       return DivideResult(a, b);
+                       typedef VectorBinaryOp<T, A, B, Divide<T> > Repr;
+                       typedef Vector<T, Repr> Vector;
+               };
+
+               template <typename T, typename A>
+               struct VectorNegate
+               { 
+                       typedef VectorUnaryOp<T, A, Negate<T> > Repr;
+                       typedef Vector<T, Repr> Vector;
+               };
+
+               // operators
+
+               template <typename T, typename A, typename B>
+               typename VectorPlus<T, A, B>::Vector
+               operator + (const Vector<T, A>& a, const Vector<T, B>& b)
+               {
+                       typedef VectorPlus<T, A, B> Op;
+                       typedef typename Op::Vector Vector;
+                       typedef typename Op::Repr   Repr;
+                       return Vector(Repr(a.repr(), b.repr()));
                }
 
-               template <typename A>
-               typename VectorDivide<A, Scalar>::type 
-               operator / (const A& a, int b)
-               {
-                       typedef typename VectorDivide<A, Scalar>::type 
DivideResult;
-                       return DivideResult(a, Scalar(b));
+               template <typename T, typename A, typename B>
+               typename VectorMinus<T, A, B>::Vector
+               operator - (const Vector<T, A>& a, const Vector<T, B>& b)
+               {
+                       typedef VectorMinus<T, A, B> Op;
+                       typedef typename Op::Vector Vector;
+                       typedef typename Op::Repr   Repr;
+
+                       return Vector(Repr(a.repr(), b.repr()));
+               }
+
+               template <typename T, typename A>
+               typename VectorNegate<T, A>::Vector
+               operator - (const Vector<T, A>& a)
+               {
+                       typedef VectorNegate<T, A> Op;
+                       typedef typename Op::Vector Vector;
+                       typedef typename Op::Repr   Repr;
+
+                       return Vector(Repr(a.repr()));
+               }
+
+               template <typename T, typename A, typename B>
+               typename VectorMultiply<T, A, B>::Vector
+               operator * (const Vector<T, A>& a, const Vector<T, B>& b)
+               {
+                       typedef VectorMultiply<T, A, B> Op;
+                       typedef typename Op::Vector Vector;
+                       typedef typename Op::Repr   Repr;
+
+                       return Vector(Repr(a.repr(), b.repr()));
+               }
+
+               template <typename T, typename A, typename B>
+               typename VectorMultiply<T, A, Scalar<B> >::Vector
+               operator * (const Vector<T, A>& a, const B& b)
+               {
+                       typedef VectorMultiply<T, A, Scalar<B> > Op;
+                       typedef typename Op::Vector Vector;
+                       typedef typename Op::Repr   Repr;
+                       return Vector(Repr(a.repr(), Scalar<B>(b)));
+               }
+
+               template <typename T, typename A, typename B>
+               typename VectorMultiply<T, Scalar<A>, B>::Vector
+               operator * (const A& a, const Vector<T, B>& b)
+               {
+                       typedef VectorMultiply<T, Scalar<A>, B> Op;
+                       typedef typename Op::Vector Vector;
+                       typedef typename Op::Repr   Repr;
+                       return Vector(Repr(Scalar<A>(a), b.repr()));
+               }
+
+               template <typename T, typename A, typename B>
+               typename VectorDivide<T, A, B>::Vector
+               operator / (const Vector<T, A>& a, const Vector<T, B>& b)
+               {
+                       typedef VectorDivide<T, A, B> Op;
+                       typedef typename Op::Vector Vector;
+                       typedef typename Op::Repr   Repr;
+                       return Vector(Repr(a.repr(), b.repr()));
                }
+
+               template <typename T, typename A, typename B>
+               typename VectorDivide<T, A, Scalar<B> >::Vector
+               operator / (const Vector<T, A>& a, const B& b)
+               {
+                       typedef VectorDivide<T, A, Scalar<B> > Op;
+                       typedef typename Op::Vector Vector;
+                       typedef typename Op::Repr   Repr;
+                       return Vector(Repr(a.repr(), Scalar<B>(b)));
+               }
                
        } // namespace math
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]