00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef NTG_VECT_VEC_HH
00029 # define NTG_VECT_VEC_HH
00030
00031 # include <ntg/basics.hh>
00032 # include <ntg/core/internal/macros.hh>
00033 # include <ntg/vect/vect_value.hh>
00034
00035 # include <mlc/array/all.hh>
00036 # include <mlc/type.hh>
00037
00038
00039
00040
00041
00042 # define ASSIGN_VECTOR_VECTOR_OPERATOR(Name, Op) \
00043 template <class T1, class T2> inline \
00044 static T1& \
00045 Name(T1& lhs, const T2& rhs) \
00046 { \
00047 ntg_is_a(T1, ntg::vectorial)::ensure(); \
00048 ntg_is_a(T2, ntg::vectorial)::ensure(); \
00049 precondition(lhs.size() == rhs.size()); \
00050 unsigned s = lhs.size(); \
00051 for (unsigned i = 0; i < s; ++i) \
00052 lhs[i] Op rhs[i]; \
00053 return lhs; \
00054 }
00055
00056 # define ASSIGN_VECTOR_SCALAR_OPERATOR(Name, Op) \
00057 template <class T1, class T2> inline \
00058 static T1& \
00059 Name(T1& lhs, const T2& rhs) \
00060 { \
00061 ntg_is_a(T1, ntg::vectorial)::ensure(); \
00062 ntg_is_a(T2, ntg::real)::ensure(); \
00063 unsigned s = lhs.size(); \
00064 for (unsigned i = 0; i < s; ++i) \
00065 lhs[i] Op rhs; \
00066 return lhs; \
00067 }
00068
00069 # define ARITH_VECTOR_VECTOR_OPERATOR(Name, Op) \
00070 template <class T1, class T2> \
00071 inline static \
00072 ntg_return_type(Name,T1, T2) \
00073 Name(const T1& lhs, const T2& rhs) \
00074 { \
00075 ntg_is_a(T1, ntg::vectorial)::ensure(); \
00076 ntg_is_a(T2, ntg::vectorial)::ensure(); \
00077 typedef ntg_return_type(Name,T1, T2) return_type; \
00078 return_type result(lhs); \
00079 result Op rhs; \
00080 return result; \
00081 }
00082
00083 namespace ntg {
00084
00085 namespace internal {
00086
00087
00088
00089
00090
00091 template <unsigned N, class T, class Self>
00092 struct typetraits<vec<N, T, Self> > : public typetraits<vect_value<vec<N, T, Self> > >
00093 {
00094 enum { nb_comp = N };
00095
00096 typedef vec<N, T, Self> self;
00097 typedef vectorial abstract_type;
00098 typedef self ntg_type;
00099 typedef optraits<self> optraits_type;
00100
00101 ntg_build_value_type(vect_value<E>);
00102
00103
00104 typedef T comp_type;
00105 typedef self base_type;
00106 typedef T storage_type[N];
00107 typedef typename typetraits<T>::cumul_type cumul_type[N];
00108
00109 static const self &sup()
00110 {
00111 static self tmp = mkSup();
00112
00113 return tmp;
00114 };
00115
00116 protected:
00117 static self mkSup()
00118 {
00119 self tmp;
00120
00121 for (unsigned i = 0; i < N; ++i)
00122 tmp[i] = ntg_sup_val(T);
00123 return tmp;
00124 };
00125 };
00126
00127 }
00128
00129
00130
00131
00132
00133 template <unsigned N, class T, class E>
00134 class vec :
00135 public vect_value<typename mlc::exact_vt<vec<N, T, mlc::final>, E>::ret>
00136 {
00137 public :
00138
00139 vec()
00140 {
00141 _fill (ntg_zero_val(T));
00142 }
00143
00144
00145 template<int ncols, class T2>
00146 vec(const mlc::array2d< mlc::array2d_info<1, ncols>, T2>& arr)
00147 {
00148 mlc::is_true< ncols == N >::ensure();
00149 for (unsigned i = 0; i < N; ++i)
00150 this->val_[i] = arr[i];
00151 }
00152
00153 template<class U, class E2>
00154 vec(const vec<N, U, E2>& v)
00155 {
00156 for (unsigned i = 0; i < N; ++i)
00157 this->val_[i] = v[i];
00158 }
00159
00160 template<class U, class E2>
00161 vec<N, T>& operator=(const vec<N, U, E2>& v)
00162 {
00163 for (unsigned i = 0; i < N; ++i)
00164 this->val_[i] = v[i];
00165 return *this;
00166 }
00167
00168 static const vec<N,T> zero() { return vec(); }
00169
00170
00171 ~vec() {}
00172
00173 protected:
00174 vec& _fill(T t)
00175 {
00176 for (unsigned i = 0; i < N; ++i)
00177 this->val_[i] = t;
00178 return *this;
00179 }
00180 };
00181
00182 template<unsigned N,class T> inline
00183 std::ostream&
00184 operator<<(std::ostream& ostr, const vec<N,T>& rhs)
00185 {
00186
00187
00188
00189
00190 std::ostringstream str;
00191 str << "[";
00192 for (unsigned i = 0; i < N; ++i)
00193 str << rhs[i] << ((i < N-1) ? "," : "]");
00194 ostr << str.str();
00195 return ostr;
00196 }
00197
00198 namespace internal
00199 {
00200
00201
00202
00203
00204
00205 template <unsigned N, class T, class E>
00206 class optraits<vec<N, T, E> > : public optraits<vect_value<vec<N, T, E> > >
00207 {
00208 typedef vec<N, T, E> self;
00209 typedef ntgi_storage_type(self) storage_type_;
00210
00211 public:
00212 static self zero ()
00213 {
00214
00215 return self();
00216 }
00217
00218 static unsigned max_print_width ()
00219 {
00220 return (N * ntg_max_print_width(T)) + (N - 1) + 2;
00221 }
00222
00223 static std::string
00224 name() {
00225 std::ostringstream out;
00226 out << "vec<" << N << ", " << ntg_name(T) << ">"<< std::ends;
00227 return out.str();
00228 }
00229
00230
00231
00232
00233 ASSIGN_VECTOR_VECTOR_OPERATOR(plus_equal, +=)
00234 ASSIGN_VECTOR_VECTOR_OPERATOR(minus_equal, -=)
00235 ASSIGN_VECTOR_SCALAR_OPERATOR(times_equal, *=)
00236 ASSIGN_VECTOR_SCALAR_OPERATOR(div_equal, /=)
00237 ASSIGN_VECTOR_SCALAR_OPERATOR(mod_equal, %=)
00238
00239 ARITH_VECTOR_VECTOR_OPERATOR(plus, +=)
00240 ARITH_VECTOR_VECTOR_OPERATOR(minus, -=)
00241
00242
00243
00244 template <class T1, class T2>
00245 inline static
00246 ntg_return_type(div, T1, T2)
00247 div(const T1& lhs, const T2& rhs)
00248 {
00249 ntg_is_a(T1, ntg::vectorial)::ensure();
00250 ntg_is_a(T2, ntg::real)::ensure();
00251 typedef ntg_return_type(div, T1, T2) return_type;
00252 return_type result(lhs);
00253 result /= rhs;
00254 return result;
00255 }
00256
00257
00258
00259 template <class T1, class T2>
00260 inline static
00261 ntg_return_type(mod, T1, T2)
00262 mod(const T1& lhs, const T2& rhs)
00263 {
00264 ntg_is_a(T1, ntg::vectorial)::ensure();
00265 ntg_is_a(T2, ntg::real)::ensure();
00266 typedef ntg_return_type(mod, T1, T2) return_type;
00267 return_type result(lhs);
00268 result %= rhs;
00269 return result;
00270 }
00271
00272
00273
00274
00275 template <unsigned M, class T1, class T2>
00276 inline static typename
00277 internal::deduce_from_traits<internal::operator_times,
00278 vec<M, T1>,
00279 vec<M, T2> >::ret
00280 times(const vec<M, T1>& lhs, const vec<M, T2>& rhs)
00281 {
00282 typedef vec<M, T1> vec1;
00283 typedef vec<M, T2> vec2;
00284 ntg_is_a(vec1, ntg::vectorial)::ensure();
00285 ntg_is_a(vec2, ntg::vectorial)::ensure();
00286 typedef typename
00287 internal::deduce_from_traits<internal::operator_times,
00288 vec<M, T1>, vec<M, T2> >::ret return_type;
00289 precondition(lhs.size() == rhs.size());
00290
00291 return_type result = optraits<return_type>::zero();
00292 unsigned s = lhs.size();
00293 for (unsigned i = 0; i < s; ++i)
00294 result += lhs[i] * rhs[i];
00295
00296 return result;
00297 }
00298
00299
00300 template <class T1, class T2>
00301 inline static
00302 ntg_return_type(times, T1, T2)
00303 times(const vect_value<T1>& lhs, const T2& rhs)
00304 {
00305 ntg_is_a(T1, ntg::vectorial)::ensure();
00306 ntg_is_a(T2, ntg::real)::ensure();
00307 typedef ntg_return_type(times, T1, T2) return_type;
00308 return_type result(lhs.exact());
00309 result *= rhs;
00310 return result;
00311 }
00312
00313
00314 template <class T1, class T2>
00315 inline static
00316 ntg_return_type(times, T1, T2)
00317 times(const T1& lhs, const vect_value<T2>& rhs)
00318 {
00319 return times(rhs, lhs);
00320 }
00321
00322
00323 template <class T1, class T2>
00324 inline static bool
00325 cmp_eq (const T1& lhs, const T2& rhs)
00326 {
00327 ntg_is_a(T1, ntg::vectorial)::ensure();
00328 ntg_is_a(T2, ntg::vectorial)::ensure();
00329 ntg_assert(lhs.size() == rhs.size());
00330
00331 typedef ntg_return_type(cmp, T1, T2) tmp_type;
00332
00333 unsigned s = lhs.size();
00334 for (unsigned i = 0; i < s; ++i)
00335 if (lhs[i] != rhs[i])
00336 return false;
00337 return true;
00338 }
00339 };
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351 template<unsigned N, class T1, class T2, class S1, class S2>
00352 struct operator_traits<operator_plus, vec<N, T1, S1>, vec<N, T2, S2> >
00353 {
00354 enum { commutative = true };
00355 typedef vec<N, ntg_return_type(plus, T1, T2)> ret;
00356 typedef vec<N, T1> impl;
00357 };
00358
00359
00360
00361
00362
00363
00364
00365 template<unsigned N, class T1, class T2>
00366 struct operator_traits<operator_minus, vec<N, T1>, vec<N, T2> >
00367 {
00368 enum { commutative = true };
00369 typedef vec<N, ntg_return_type(minus, T1, T2)> ret;
00370 typedef vec<N, T1> impl;
00371 };
00372
00373
00374
00375
00376
00377
00378
00379 template<unsigned N, class T1, class T2>
00380 struct operator_traits<operator_times, vec<N, T1>, T2>
00381 {
00382 enum { commutative = true };
00383 typedef vec<N, ntg_return_type(times, T1, T2)> ret;
00384 typedef vec<N, T1> impl;
00385 };
00386
00387
00388
00389 template<unsigned N, class T1, class T2>
00390 struct operator_traits<operator_times, vec<N, T1>, vec<N, T2> >
00391 {
00392 enum { commutative = true };
00393 typedef ntg_return_type(times,T1,T2) t;
00394 typedef typename typetraits<t>::cumul_type ret;
00395 typedef vec<N, T1> impl;
00396 };
00397
00398
00399
00400
00401
00402
00403
00404 template<unsigned N, class T1, class T2>
00405 struct operator_traits<operator_div, vec<N, T1>, T2>
00406 {
00407 enum { commutative = false };
00408 typedef vec<N, ntg_return_type(div, T1, T2)> ret;
00409 typedef vec<N, T1> impl;
00410 };
00411
00412
00413
00414
00415
00416
00417
00418 template<unsigned N, class T1, class T2>
00419 struct operator_traits<operator_mod, vec<N, T1>, T2>
00420 {
00421 enum { commutative = false };
00422 typedef vec<N, ntg_return_type(mod, T1, T2)> ret;
00423 typedef vec<N, T1> impl;
00424 };
00425
00426
00427
00428
00429
00430
00431
00432 template<unsigned N, class T1, class T2, class S1, class S2>
00433 struct operator_traits<operator_cmp, vec<N, T1, S1>, vec<N, T2, S2> >
00434 {
00435 enum { commutative = true };
00436 typedef vec<N, ntg_return_type(cmp, T1, T2)> ret;
00437 typedef vec<N, T1> impl;
00438 };
00439
00440 }
00441
00442 }
00443
00444 #endif // !NTG_VECT_VEC_HH