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