/[usata]/usata2/src/math/vector-template.hpp
ViewVC logotype

Diff of /usata2/src/math/vector-template.hpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1 by Descender, Mon Jan 10 08:14:52 2005 UTC revision 1.2 by Descender, Sat Jan 22 10:02:10 2005 UTC
# Line 14  Line 14 
14  #ifndef USATA_VECTOR_TEMPLATE_HPP  #ifndef USATA_VECTOR_TEMPLATE_HPP
15  #define USATA_VECTOR_TEMPLATE_HPP  #define USATA_VECTOR_TEMPLATE_HPP
16    
17    #include <boost/format.hpp>
18    #include <boost/concept_check.hpp>
19    
20  namespace usata  namespace usata
21  {  {
22          namespace math          namespace math
23          {          {
24    
25                    // NOTE: I'm somewhat forced to define operator function
26                    // parameter type for VectorUnaryOp and VectorBinaryOp as a
27                    // class instead of template function references because GCC
28                    // <= 4.0 throws an ICE in our face - descender
29    
30                    template <typename T>
31                  class Scalar;                  class Scalar;
32    
33                    template <typename T, int N>
34                    class Array;
35    
36                    template <typename T, typename ReprT = Array<T, 4> >
37                  class Vector;                  class Vector;
38    
39                  template <typename A, typename B, typename BinaryOp>                  template <typename T, typename A, typename UnaryOp>
40                    class VectorUnaryOp;
41    
42                    template <typename T, typename A, typename B, typename BinaryOp>
43                  class VectorBinaryOp;                  class VectorBinaryOp;
44    
45                    // convenient typedefs
46    
47                    typedef Vector<int>    Vector4i;
48                    typedef Vector<float>  Vector4f;
49                    typedef Vector<double> Vector4d;
50    
51    
52                    // concepts
53    
54                    template <typename T>
55                    struct IsNumericConcept
56                    {
57                            void
58                            constraints()
59                            {
60                                    boost::function_requires<boost::ComparableConcept<T> >();
61    
62                                    T a, b, c;
63                                    c = a + b;
64                                    c = a - b;
65                                    c = a * b;
66                                    c = a / b;
67                                    c = -a;
68                            }
69                    };
70    
71    
72                    // Operand copying semantics
73    
74                  template <typename T>                  template <typename T>
75                  struct OperandTraits                  struct OperandTraits
76                  {                          {
77                          typedef const T& Ref;                          typedef const T& Ref;
78                  };                  };
79    
80                  template <>                  template <typename T>
81                  struct OperandTraits<Scalar>                  struct OperandTraits<Scalar<T> >
82                  {                  {
83                          typedef Scalar Ref;                          typedef Scalar<T> Ref;
84                  };                  };
85    
86    
87                    template <typename T>
88                  class Scalar                  class Scalar
89                  {                  {
90                  public:                  public:
91    
92                          Scalar(int x)                          explicit Scalar(T x)
93                                  : m_x(x)                                  : m_x(x)
94                          {}                          {}
95    
96                          ~Scalar()                          T
                         {}  
   
                         int  
97                          operator [] (int index) const                          operator [] (int index) const
98                          {                          {
99                                  return m_x;                                  return m_x;
# Line 56  namespace usata Line 101  namespace usata
101    
102                  private:                  private:
103    
104                          int m_x;                          T m_x;
105                    };
106    
107    
108                    template <typename T, int N>
109                    class Array
110                    {
111                    public:
112    
113                            T
114                            operator [] (int index) const
115                            {
116                                    return m_elements[index];
117                            }
118    
119                            T&
120                            operator [] (int index)
121                            {
122                                    return m_elements[index];
123                            }
124    
125                    private:
126    
127                            T m_elements[N];
128                  };                  };
129    
130                  class Vector  
131                    template <typename T, typename ReprT>
132                    class Vector
133                  {                  {
134                  public:                  public:
135                            BOOST_CLASS_REQUIRE(T, usata::math, IsNumericConcept);
136    
137                          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)
138                          {                          {
139                                  v[0] = x;                                  m_repr[0] = x;
140                                  v[1] = y;                                  m_repr[1] = y;
141                                  v[2] = z;                                  m_repr[2] = z;
142                                  v[3] = w;                                  m_repr[3] = w;
143                          }                          }
144              
145                          template <typename T>                          // NOTE: GCC (and probably other compilers) can't optimize
146                            // this call away - descender
147                            Vector(const ReprT& repr)
148                                    : m_repr(repr)
149                            {}
150    
151                            template <typename ReprT2>
152                          Vector&                          Vector&
153                          operator = (const T& expr)                          operator = (const Vector<T, ReprT2>& rhs)
154                          {                          {
155                                  v[0] = expr[0];                                  m_repr[0] = rhs[0];
156                                  v[1] = expr[1];                                  m_repr[1] = rhs[1];
157                                  v[2] = expr[2];                                  m_repr[2] = rhs[2];
158                                  v[3] = expr[3];                                  m_repr[3] = rhs[3];
159                                  return *this;                                  return *this;
160                          }                          }
161    
162                            ReprT&
163                            repr()
164                            {
165                                    T x;
166                                    return x.cannot_be_used_as_lvalue_error();
167                            }
168    
169                            // rvalue
170                            const ReprT&
171                            repr() const
172                            {
173                                    return m_repr;
174                            }
175    
176                          // lvalue                          // lvalue
177                          int&                          T&
178                          operator [] (int index)                          operator [] (int index)
179                          {                          {
180                                  return v[index];                                  return m_repr[index];
181                          }                          }
182    
183                          // rvalue                          // rvalue
184                          int                          T
185                          operator [] (int index) const                          operator [] (int index) const
186                          {                          {
187                                  return v[index];                                  return m_repr[index];
188                          }                          }
189    
190                          friend std::ostream&                          friend std::ostream&
# Line 101  namespace usata Line 192  namespace usata
192                          {                          {
193                                  return out << boost::format("[%1% %2% %3% %4%]")                                  return out << boost::format("[%1% %2% %3% %4%]")
194                                          % v[0] % v[1] % v[2] % v[3];                                          % v[0] % v[1] % v[2] % v[3];
   
195                          }                          }
196    
197                  private:                  private:
198    
199                          int v[4];                          ReprT m_repr;
200                  };                  };
201    
202                  template <typename A, typename UnaryOp>  
203                    template <typename T, typename A, typename UnaryOp>
204                  class VectorUnaryOp                  class VectorUnaryOp
205                  {                  {
206                  public:                  public:
207                            BOOST_CLASS_REQUIRE(T, usata::math, IsNumericConcept);
208    
209                          VectorUnaryOp(const A& a)                          VectorUnaryOp(const A& a)
210                                  : m_a(a)                                  : m_a(a)
211                          {}                          {}
212    
213                          int                          T
214                          operator [] (int index) const                          operator [] (int index) const
215                          {                          {
216                                  return UnaryOp::eval(m_a[index]);                                  return UnaryOp::eval(m_a[index]);
217                          }                          }
218    
219                            T&
220                            operator [] (int index)
221                            {
222                                    T x;
223                                    return x.cannot_be_used_as_lvalue_error();
224                            }
225    
226                  private:                  private:
227    
228                          typename OperandTraits<A>::Ref m_a;                          typename OperandTraits<A>::Ref m_a;
229                  };                  };
230    
231                  template <typename A, typename B, typename BinaryOp>                  template <typename T, typename A, typename B, typename BinaryOp>
232                  class VectorBinaryOp                  class VectorBinaryOp
233                  {                  {
234                  public:                  public:
235                            BOOST_CLASS_REQUIRE(T, usata::math, isNumericConcept);
236    
237                          VectorBinaryOp(const A& a, const B& b)                          VectorBinaryOp(const A& a, const B& b)
238                                  : m_a(a),                                  : m_a(a),
239                                    m_b(b)                                    m_b(b)
240                          {}                          {}
241    
242                          int                          T
243                          operator [] (int index) const                          operator [] (int index) const
244                          {                          {
245                                  return BinaryOp::eval(m_a[index], m_b[index]);                                  return BinaryOp::eval(m_a[index], m_b[index]);
246                          }                          }
247    
248                            T&
249                            operator [] (int index)
250                            {
251                                    T x;
252                                    return x.cannot_be_used_as_lvalue_error();
253                            }
254    
255                  private:                  private:
256    
257                          typename OperandTraits<A>::Ref m_a;                          typename OperandTraits<A>::Ref m_a;
# Line 152  namespace usata Line 259  namespace usata
259                  };                  };
260    
261    
262                  struct plus     { static int eval(int a, int b) { return a + b; } };                  template <typename T>
263                  struct minus    { static int eval(int a, int b) { return a - b; } };                  struct Plus
                 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)  
264                  {                  {
265                          typedef typename VectorPlus<A,B>::type PlusResult;                          static T
266                          return PlusResult(a, b);                          eval(T a, T b)
267                  }                          {
268                                    return a + b;
269                            }
270                    };
271    
272                  template <typename A, typename B>                  template <typename T>
273                  typename VectorMinus<A, B>::type                  struct Minus
                 operator - (const A& a, const B& b)  
274                  {                  {
275                          typedef typename VectorMinus<A,B>::type MinusResult;                          static T
276                          return MinusResult(a, b);                          eval(T a, T b)
277                  }                          {
278                                    return a - b;
279                            }
280                    };
281    
282                  template <typename A>                  template <typename T>
283                  typename VectorNegate<A>::type                  struct Multiply
                 operator - (const A& a)  
284                  {                  {
285                          typedef typename VectorNegate<A>::type NegateResult;                          static T
286                          return NegateResult(a);                          eval(T a, T b)
287                  }                          {
288                                    return a * b;
289                            }
290                    };
291                            
292                    template <typename T>
293                    struct Divide
294                    {
295                            static T
296                            eval(T a, T b)
297                            {
298                                    return a / b;
299                            }
300                    };
301    
302                  template <typename A, typename B>                  template <typename T>
303                  typename VectorMultiply<A, B>::type                  struct Negate
                 operator * (const A& a, const B& b)  
304                  {                  {
305                          typedef typename VectorMultiply<A,B>::type MultiplyResult;                          static T
306                          return MultiplyResult(a, b);                          eval(T a)
307                  }                          {
308                                    return -a;
309                            }
310                    };
311                    
312                    template <typename T, typename A, typename B>
313                    struct VectorPlus
314                    {
315                            typedef VectorBinaryOp<T, A, B, Plus<T> > Repr;
316                            typedef Vector<T, Repr> Vector;
317                    };
318    
319                  template <typename A>                  template <typename T, typename A, typename B>
320                  typename VectorMultiply<A, Scalar>::type                  struct VectorMinus
                 operator * (const A& a, int b)  
321                  {                  {
322                          typedef typename VectorMultiply<A, Scalar>::type MultiplyResult;                          typedef VectorBinaryOp<T, A, B, Minus<T> > Repr;
323                          return MultiplyResult(a, Scalar(b));                          typedef Vector<T, Repr> Vector;
324                  }                  };
325    
326                  template <typename B>                  template <typename T, typename A, typename B>
327                  typename VectorMultiply<Scalar, B>::type                  struct VectorMultiply
                 operator * (int a, const B& b)  
328                  {                  {
329                          typedef typename VectorMultiply<Scalar, B>::type MultiplyResult;                          typedef VectorBinaryOp<T, A, B, Multiply<T> > Repr;
330                          return MultiplyResult(Scalar(a), b);                          typedef Vector<T, Repr> Vector;
331                  }                  };
332    
333                  template <typename A, typename B>                  template <typename T, typename A, typename B>
334                  typename VectorDivide<A, B>::type                  struct VectorDivide
                 operator / (const A& a, const B& b)  
335                  {                  {
336                          typedef typename VectorDivide<A,B>::type DivideResult;                          typedef VectorBinaryOp<T, A, B, Divide<T> > Repr;
337                          return DivideResult(a, b);                          typedef Vector<T, Repr> Vector;
338                    };
339    
340                    template <typename T, typename A>
341                    struct VectorNegate
342                    {
343                            typedef VectorUnaryOp<T, A, Negate<T> > Repr;
344                            typedef Vector<T, Repr> Vector;
345                    };
346    
347                    // operators
348    
349                    template <typename T, typename A, typename B>
350                    typename VectorPlus<T, A, B>::Vector
351                    operator + (const Vector<T, A>& a, const Vector<T, B>& b)
352                    {
353                            typedef VectorPlus<T, A, B> Op;
354                            typedef typename Op::Vector Vector;
355                            typedef typename Op::Repr   Repr;
356                            return Vector(Repr(a.repr(), b.repr()));
357                  }                  }
358    
359                  template <typename A>                  template <typename T, typename A, typename B>
360                  typename VectorDivide<A, Scalar>::type                  typename VectorMinus<T, A, B>::Vector
361                  operator / (const A& a, int b)                  operator - (const Vector<T, A>& a, const Vector<T, B>& b)
362                  {                  {
363                          typedef typename VectorDivide<A, Scalar>::type DivideResult;                          typedef VectorMinus<T, A, B> Op;
364                          return DivideResult(a, Scalar(b));                          typedef typename Op::Vector Vector;
365                            typedef typename Op::Repr   Repr;
366    
367                            return Vector(Repr(a.repr(), b.repr()));
368                    }
369    
370                    template <typename T, typename A>
371                    typename VectorNegate<T, A>::Vector
372                    operator - (const Vector<T, A>& a)
373                    {
374                            typedef VectorNegate<T, A> Op;
375                            typedef typename Op::Vector Vector;
376                            typedef typename Op::Repr   Repr;
377    
378                            return Vector(Repr(a.repr()));
379                    }
380    
381                    template <typename T, typename A, typename B>
382                    typename VectorMultiply<T, A, B>::Vector
383                    operator * (const Vector<T, A>& a, const Vector<T, B>& b)
384                    {
385                            typedef VectorMultiply<T, A, B> Op;
386                            typedef typename Op::Vector Vector;
387                            typedef typename Op::Repr   Repr;
388    
389                            return Vector(Repr(a.repr(), b.repr()));
390                    }
391    
392                    template <typename T, typename A, typename B>
393                    typename VectorMultiply<T, A, Scalar<B> >::Vector
394                    operator * (const Vector<T, A>& a, const B& b)
395                    {
396                            typedef VectorMultiply<T, A, Scalar<B> > Op;
397                            typedef typename Op::Vector Vector;
398                            typedef typename Op::Repr   Repr;
399                            return Vector(Repr(a.repr(), Scalar<B>(b)));
400                    }
401    
402                    template <typename T, typename A, typename B>
403                    typename VectorMultiply<T, Scalar<A>, B>::Vector
404                    operator * (const A& a, const Vector<T, B>& b)
405                    {
406                            typedef VectorMultiply<T, Scalar<A>, B> Op;
407                            typedef typename Op::Vector Vector;
408                            typedef typename Op::Repr   Repr;
409                            return Vector(Repr(Scalar<A>(a), b.repr()));
410                    }
411    
412                    template <typename T, typename A, typename B>
413                    typename VectorDivide<T, A, B>::Vector
414                    operator / (const Vector<T, A>& a, const Vector<T, B>& b)
415                    {
416                            typedef VectorDivide<T, A, B> Op;
417                            typedef typename Op::Vector Vector;
418                            typedef typename Op::Repr   Repr;
419                            return Vector(Repr(a.repr(), b.repr()));
420                  }                  }
421    
422                    template <typename T, typename A, typename B>
423                    typename VectorDivide<T, A, Scalar<B> >::Vector
424                    operator / (const Vector<T, A>& a, const B& b)
425                    {
426                            typedef VectorDivide<T, A, Scalar<B> > Op;
427                            typedef typename Op::Vector Vector;
428                            typedef typename Op::Repr   Repr;
429                            return Vector(Repr(a.repr(), Scalar<B>(b)));
430                    }
431                                    
432          } // namespace math          } // namespace math
433    

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26