[Top][All Lists]
[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