00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef VEC_H
00012 #define VEC_H
00013
00014
00015 #include "Message/Message.h"
00016
00018
00019 template<class T, unsigned Length>
00020 class vec
00021 {
00022 public:
00023 vec() {}
00024 vec(T v0);
00025 vec(T v0, T v1);
00026 vec(T v0, T v1, T v2);
00027 #ifdef IPPL_USE_FUNKY_VEC_COPIES
00028 vec( const vec<T,Length>& );
00029 vec<T,Length>& operator=( const vec<T,Length>& );
00030 #endif
00031 T& operator[](unsigned d) { return Ptr[d]; }
00032 const T& operator[](unsigned d) const { return Ptr[d]; }
00033 Message& putMessage(Message &m) {
00034 #ifdef IPPL_USE_MEMBER_TEMPLATES
00035 m.put(Ptr, Ptr + Length);
00036 #else
00037 putMessage(m,Ptr,Ptr+Length);
00038 #endif
00039 return m;
00040 }
00041 Message& getMessage(Message &m) {
00042 #ifdef IPPL_USE_MEMBER_TEMPLATES
00043 m.get_iter(Ptr);
00044 #else
00045 getMessage_iter(m,Ptr);
00046 #endif
00047 return m;
00048 }
00049
00050 static T dot(const T*,const T*);
00051 private:
00052 T Ptr[Length];
00053 };
00054
00056
00057 #ifdef IPPL_USE_FUNKY_VEC_COPIES
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 template<unsigned Length, int Flag>
00076 class DivideVecCopyTag {
00077 #ifdef IPPL_PURIFY
00078
00079 public:
00080 DivideVecCopyTag() {}
00081 DivideVecCopyTag(const DivideVecCopyTag<Length,Flag> &) {}
00082 DivideVecCopyTag<Length,Flag>&
00083 operator=(const DivideVecCopyTag<Length,Flag> &) { return *this; }
00084 #endif
00085 };
00086
00087
00088
00089
00090
00091
00092
00093 template<class T1, class T2, unsigned L>
00094 inline void
00095 divide_vec_copy(T1 *p1, T2 *p2, DivideVecCopyTag<L,4> )
00096 {
00097 divide_vec_copy(p1, p2, DivideVecCopyTag< L/2 , (L>=8 ? 4 : L/2)>());
00098 divide_vec_copy(p1+(L/2), p2+(L/2),DivideVecCopyTag<L-L/2,(L>=8?4:L-L/2)>());
00099 }
00100
00101
00102
00103
00104 template<class T1, class T2>
00105 inline void
00106 divide_vec_copy(T1 *p1, T2 *p2, DivideVecCopyTag<3,3> )
00107 {
00108 p1[0] = p2[0];
00109 p1[1] = p2[1];
00110 p1[2] = p2[2];
00111 }
00112
00113 template<class T1, class T2>
00114 inline void
00115 divide_vec_copy(T1 *p1, T2 *p2, DivideVecCopyTag<2,2> )
00116 {
00117 p1[0] = p2[0];
00118 p1[1] = p2[1];
00119 }
00120
00121 template<class T1, class T2>
00122 inline void
00123 divide_vec_copy(T1 *p1, T2 *p2, DivideVecCopyTag<1,1> )
00124 {
00125 *p1 = *p2;
00126 }
00127
00128 template<class T1, class T2>
00129 inline void
00130 divide_vec_copy(T1 *,T2 *, DivideVecCopyTag<0,0> )
00131 {
00132 }
00133
00134
00135
00136
00137
00138 template<class T, unsigned L>
00139 inline
00140 vec<T,L>::vec( const vec<T,L>& v )
00141 {
00142 divide_vec_copy( Ptr , v.Ptr , DivideVecCopyTag<L,( L>=4 ? 4 : L)>() );
00143 }
00144
00145 template<class T, unsigned L>
00146 inline vec<T,L>&
00147 vec<T,L>::operator=( const vec<T,L>& v )
00148 {
00149 if ( this != &v )
00150 divide_vec_copy( Ptr , v.Ptr , DivideVecCopyTag<L,( L>=4 ? 4 : L)>() );
00151 return *this;
00152 }
00153
00154 #endif // IPPL_USE_FUNKY_VEC_COPIES
00155
00157
00158 template<class T, unsigned Length>
00159 inline
00160 vec<T,Length>::vec(T v0)
00161 {
00162 CTAssert(Length==1);
00163 Ptr[0] = v0;
00164 }
00165
00166 template<class T, unsigned Length>
00167 inline
00168 vec<T,Length>::vec(T v0, T v1)
00169 {
00170 CTAssert(Length==2);
00171 Ptr[0] = v0;
00172 Ptr[1] = v1;
00173 }
00174
00175 template<class T, unsigned Length>
00176 inline
00177 vec<T,Length>::vec(T v0, T v1, T v2)
00178 {
00179 CTAssert(Length==3);
00180 Ptr[0] = v0;
00181 Ptr[1] = v1;
00182 Ptr[2] = v2;
00183 }
00184
00186
00187
00188
00189
00190
00191 template<class T, unsigned Length>
00192 inline T
00193 vec<T,Length>::dot(const T* l, const T* r)
00194 {
00195 T ret = l[0]*r[0];
00196 for (int i=1; i<Length; ++i)
00197 ret += l[i]*r[i];
00198 return ret;
00199 }
00200
00202
00203 #endif // VEC_H
00204
00205
00206
00207
00208
00209