00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef TVMET_VECTOR_H
00025 #define TVMET_VECTOR_H
00026
00027 #include <iterator>
00028
00029 #include <tvmet/tvmet.h>
00030 #include <tvmet/TypePromotion.h>
00031 #include <tvmet/CommaInitializer.h>
00032 #include <tvmet/RunTimeError.h>
00033
00034 #include <tvmet/xpr/Vector.h>
00035
00036 namespace tvmet {
00037
00038
00039
00040 template<class T, std::size_t Sz> class Vector;
00041
00042
00047 template<class T, std::size_t Sz>
00048 class VectorConstReference
00049 : public TvmetBase< VectorConstReference<T, Sz> >
00050 {
00051 public:
00052 typedef T value_type;
00053 typedef T* pointer;
00054 typedef const T* const_pointer;
00055
00056 public:
00058 enum {
00059 Size = Sz
00060 };
00061
00062 public:
00064 enum {
00065 ops = Size
00066 };
00067
00068 private:
00069 VectorConstReference();
00070 VectorConstReference& operator=(const VectorConstReference&);
00071
00072 public:
00074 explicit VectorConstReference(const Vector<T, Size>& rhs)
00075 : m_data(rhs.data())
00076 { }
00077
00079 explicit VectorConstReference(const_pointer data)
00080 : m_data(data)
00081 { }
00082
00083 public:
00085 value_type operator()(std::size_t i) const {
00086 TVMET_RT_CONDITION(i < Size, "VectorConstReference Bounce Violation")
00087 return m_data[i];
00088 }
00089
00090 public:
00091 void print_xpr(std::ostream& os, std::size_t l=0) const {
00092 os << IndentLevel(l)
00093 << "VectorConstReference[O=" << ops << "]<"
00094 << "T=" << typeid(T).name() << ">,"
00095 << std::endl;
00096 }
00097
00098 private:
00099 const_pointer _tvmet_restrict m_data;
00100 };
00101
00102
00107 template<class T, std::size_t Sz>
00108 class Vector
00109 {
00110 public:
00112 typedef T value_type;
00113
00115 typedef T& reference;
00116
00118 typedef const T& const_reference;
00119
00121 typedef T* iterator;
00122
00124 typedef const T* const_iterator;
00125
00127 typedef std::reverse_iterator<iterator> reverse_iterator;
00128
00130 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00131
00132 public:
00134 enum {
00135 Size = Sz
00136 };
00137
00138 public:
00140 enum {
00141 ops_assign = Size,
00142 ops = ops_assign,
00143 use_meta = ops < TVMET_COMPLEXITY_V_ASSIGN_TRIGGER ? true : false
00144 };
00145
00146 public:
00148 iterator begin() { return m_data; }
00149
00151 iterator end() { return m_data + Size; }
00152
00154 const_iterator begin() const { return m_data; }
00155
00157 const_iterator end() const { return m_data + Size; }
00158
00160 reverse_iterator rbegin() { return reverse_iterator( end() ); }
00161
00163 const_reverse_iterator rbegin() const {
00164 return const_reverse_iterator( end() );
00165 }
00166
00168 reverse_iterator rend() { return reverse_iterator( begin() ); }
00169
00171 const_reverse_iterator rend() const {
00172 return const_reverse_iterator( begin() );
00173 }
00174
00176 value_type front() { return m_data[0]; }
00177
00179 const_reference front() const { return m_data[0]; }
00180
00182 value_type back() { return m_data[Size-1]; }
00183
00185 const_reference back() const { return m_data[Size-1]; }
00186
00188 static bool empty() { return false; }
00189
00191 static std::size_t size() { return Size; }
00192
00194 static std::size_t max_size() { return Size; }
00195
00196 public:
00198 ~Vector() {
00199 #if defined(TVMET_DYNAMIC_MEMORY)
00200 delete [] m_data;
00201 #endif
00202 }
00203
00206 explicit Vector()
00207 #if defined(TVMET_DYNAMIC_MEMORY)
00208 : m_data( new value_type[Size] )
00209 #endif
00210 { }
00211
00213 Vector(const Vector& rhs)
00214 #if defined(TVMET_DYNAMIC_MEMORY)
00215 : m_data( new value_type[Size] )
00216 #endif
00217 {
00218 *this = XprVector<ConstReference, Size>(rhs.const_ref());
00219 }
00220
00225 template<class InputIterator>
00226 explicit Vector(InputIterator first, InputIterator last)
00227 #if defined(TVMET_DYNAMIC_MEMORY)
00228 : m_data( new value_type[Size] )
00229 #endif
00230 {
00231 TVMET_RT_CONDITION( static_cast<std::size_t>(std::distance(first, last)) <= Size,
00232 "InputIterator doesn't fits in size" )
00233 std::copy(first, last, m_data);
00234 }
00235
00240 template<class InputIterator>
00241 explicit Vector(InputIterator first, std::size_t sz)
00242 #if defined(TVMET_DYNAMIC_MEMORY)
00243 : m_data( new value_type[Size] )
00244 #endif
00245 {
00246 TVMET_RT_CONDITION( sz <= Size, "InputIterator doesn't fits in size" )
00247 std::copy(first, first + sz, m_data);
00248 }
00249
00251 explicit Vector(value_type rhs)
00252 #if defined(TVMET_DYNAMIC_MEMORY)
00253 : m_data( new value_type[Size] )
00254 #endif
00255 {
00256 typedef XprLiteral<value_type> expr_type;
00257 *this = XprVector<expr_type, Size>(expr_type(rhs));
00258 }
00259
00261 explicit Vector(value_type x0, value_type x1)
00262 #if defined(TVMET_DYNAMIC_MEMORY)
00263 : m_data( new value_type[Size] )
00264 #endif
00265 {
00266 TVMET_CT_CONDITION(2 <= Size, ArgumentList_is_too_long)
00267 m_data[0] = x0; m_data[1] = x1;
00268 }
00269
00271 explicit Vector(value_type x0, value_type x1, value_type x2)
00272 #if defined(TVMET_DYNAMIC_MEMORY)
00273 : m_data( new value_type[Size] )
00274 #endif
00275 {
00276 TVMET_CT_CONDITION(3 <= Size, ArgumentList_is_too_long)
00277 m_data[0] = x0; m_data[1] = x1; m_data[2] = x2;
00278 }
00279
00281 explicit Vector(value_type x0, value_type x1, value_type x2, value_type x3)
00282 #if defined(TVMET_DYNAMIC_MEMORY)
00283 : m_data( new value_type[Size] )
00284 #endif
00285 {
00286 TVMET_CT_CONDITION(4 <= Size, ArgumentList_is_too_long)
00287 m_data[0] = x0; m_data[1] = x1; m_data[2] = x2; m_data[3] = x3;
00288 }
00289
00291 explicit Vector(value_type x0, value_type x1, value_type x2, value_type x3,
00292 value_type x4)
00293 #if defined(TVMET_DYNAMIC_MEMORY)
00294 : m_data( new value_type[Size] )
00295 #endif
00296 {
00297 TVMET_CT_CONDITION(5 <= Size, ArgumentList_is_too_long)
00298 m_data[0] = x0; m_data[1] = x1; m_data[2] = x2; m_data[3] = x3; m_data[4] = x4;
00299 }
00300
00302 explicit Vector(value_type x0, value_type x1, value_type x2, value_type x3,
00303 value_type x4, value_type x5)
00304 #if defined(TVMET_DYNAMIC_MEMORY)
00305 : m_data( new value_type[Size] )
00306 #endif
00307 {
00308 TVMET_CT_CONDITION(6 <= Size, ArgumentList_is_too_long)
00309 m_data[0] = x0; m_data[1] = x1; m_data[2] = x2; m_data[3] = x3; m_data[4] = x4;
00310 m_data[5] = x5;
00311 }
00312
00314 explicit Vector(value_type x0, value_type x1, value_type x2, value_type x3,
00315 value_type x4, value_type x5, value_type x6)
00316 #if defined(TVMET_DYNAMIC_MEMORY)
00317 : m_data( new value_type[Size] )
00318 #endif
00319 {
00320 TVMET_CT_CONDITION(7 <= Size, ArgumentList_is_too_long)
00321 m_data[0] = x0; m_data[1] = x1; m_data[2] = x2; m_data[3] = x3; m_data[4] = x4;
00322 m_data[5] = x5; m_data[6] = x6;
00323 }
00324
00326 explicit Vector(value_type x0, value_type x1, value_type x2, value_type x3,
00327 value_type x4, value_type x5, value_type x6, value_type x7)
00328 #if defined(TVMET_DYNAMIC_MEMORY)
00329 : m_data( new value_type[Size] )
00330 #endif
00331 {
00332 TVMET_CT_CONDITION(8 <= Size, ArgumentList_is_too_long)
00333 m_data[0] = x0; m_data[1] = x1; m_data[2] = x2; m_data[3] = x3; m_data[4] = x4;
00334 m_data[5] = x5; m_data[6] = x6; m_data[7] = x7;
00335 }
00336
00338 explicit Vector(value_type x0, value_type x1, value_type x2, value_type x3,
00339 value_type x4, value_type x5, value_type x6, value_type x7,
00340 value_type x8)
00341 #if defined(TVMET_DYNAMIC_MEMORY)
00342 : m_data( new value_type[Size] )
00343 #endif
00344 {
00345 TVMET_CT_CONDITION(9 <= Size, ArgumentList_is_too_long)
00346 m_data[0] = x0; m_data[1] = x1; m_data[2] = x2; m_data[3] = x3; m_data[4] = x4;
00347 m_data[5] = x5; m_data[6] = x6; m_data[7] = x7; m_data[8] = x8;
00348 }
00349
00351 explicit Vector(value_type x0, value_type x1, value_type x2, value_type x3,
00352 value_type x4, value_type x5, value_type x6, value_type x7,
00353 value_type x8, value_type x9)
00354 #if defined(TVMET_DYNAMIC_MEMORY)
00355 : m_data( new value_type[Size] )
00356 #endif
00357 {
00358 TVMET_CT_CONDITION(10 <= Size, ArgumentList_is_too_long)
00359 m_data[0] = x0; m_data[1] = x1; m_data[2] = x2; m_data[3] = x3; m_data[4] = x4;
00360 m_data[5] = x5; m_data[6] = x6; m_data[7] = x7; m_data[8] = x8; m_data[9] = x9;
00361 }
00362
00364 template <class E>
00365 explicit Vector(const XprVector<E, Size>& e)
00366 #if defined(TVMET_DYNAMIC_MEMORY)
00367 : m_data( new value_type[Size] )
00368 #endif
00369 {
00370 *this = e;
00371 }
00372
00375 CommaInitializer<Vector, Size> operator=(value_type rhs) {
00376 return CommaInitializer<Vector, Size>(*this, rhs);
00377 }
00378
00379 public:
00380 value_type* _tvmet_restrict data() { return m_data; }
00381 const value_type* _tvmet_restrict data() const { return m_data; }
00382
00383 public:
00384 value_type& _tvmet_restrict operator()(std::size_t i) {
00385
00386 TVMET_RT_CONDITION(i < Size, "Vector Bounce Violation")
00387 return m_data[i];
00388 }
00389
00390 value_type operator()(std::size_t i) const {
00391 TVMET_RT_CONDITION(i < Size, "Vector Bounce Violation")
00392 return m_data[i];
00393 }
00394
00395 value_type& _tvmet_restrict operator[](std::size_t i) {
00396
00397 return this->operator()(i);
00398 }
00399
00400 value_type operator[](std::size_t i) const {
00401 return this->operator()(i);
00402 }
00403
00404 public:
00405 typedef VectorConstReference<T, Size> ConstReference;
00406
00408 ConstReference const_ref() const { return ConstReference(*this); }
00409
00411 XprVector<ConstReference, Size> as_expr() const {
00412 return XprVector<ConstReference, Size>(this->const_ref());
00413 }
00414
00415 private:
00417 template<class Dest, class Src, class Assign>
00418 static inline
00419 void do_assign(dispatch<true>, Dest& dest, const Src& src, const Assign& assign_fn) {
00420 meta::Vector<Size, 0>::assign(dest, src, assign_fn);
00421 }
00422
00424 template<class Dest, class Src, class Assign>
00425 static inline
00426 void do_assign(dispatch<false>, Dest& dest, const Src& src, const Assign& assign_fn) {
00427 loop::Vector<Size>::assign(dest, src, assign_fn);
00428 }
00429
00430 public:
00432 template<class T2, class Assign>
00433 void assign_to(Vector<T2, Size>& dest, const Assign& assign_fn) const {
00434 do_assign(dispatch<use_meta>(), dest, *this, assign_fn);
00435 }
00436
00437 public:
00440 template<class T2>
00441 Vector& operator=(const Vector<T2, Size>& rhs) {
00442 rhs.assign_to(*this, Fcnl_assign<value_type, T2>());
00443 return *this;
00444 }
00445
00447 template<class E>
00448 Vector& operator=(const XprVector<E, Size>& rhs) {
00449 rhs.assign_to(*this, Fcnl_assign<value_type, typename E::value_type>());
00450 return *this;
00451 }
00452
00453 private:
00454 template<class Obj, std::size_t LEN> friend class CommaInitializer;
00455
00459 Vector& assign_value(value_type rhs) {
00460 typedef XprLiteral<value_type> expr_type;
00461 *this = XprVector<expr_type, Size>(expr_type(rhs));
00462 return *this;
00463 }
00464
00465 public:
00466
00467 Vector& operator+=(value_type) TVMET_CXX_ALWAYS_INLINE;
00468 Vector& operator-=(value_type) TVMET_CXX_ALWAYS_INLINE;
00469 Vector& operator*=(value_type) TVMET_CXX_ALWAYS_INLINE;
00470 Vector& operator/=(value_type) TVMET_CXX_ALWAYS_INLINE;
00471
00472 Vector& operator%=(std::size_t) TVMET_CXX_ALWAYS_INLINE;
00473 Vector& operator^=(std::size_t) TVMET_CXX_ALWAYS_INLINE;
00474 Vector& operator&=(std::size_t) TVMET_CXX_ALWAYS_INLINE;
00475 Vector& operator|=(std::size_t) TVMET_CXX_ALWAYS_INLINE;
00476 Vector& operator<<=(std::size_t) TVMET_CXX_ALWAYS_INLINE;
00477 Vector& operator>>=(std::size_t) TVMET_CXX_ALWAYS_INLINE;
00478
00479 public:
00480
00481 template <class T2> Vector& M_add_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
00482 template <class T2> Vector& M_sub_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
00483 template <class T2> Vector& M_mul_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
00484 template <class T2> Vector& M_div_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
00485 template <class T2> Vector& M_mod_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
00486 template <class T2> Vector& M_xor_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
00487 template <class T2> Vector& M_and_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
00488 template <class T2> Vector& M_or_eq (const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
00489 template <class T2> Vector& M_shl_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
00490 template <class T2> Vector& M_shr_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
00491
00492 public:
00493
00494 template <class E> Vector& M_add_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
00495 template <class E> Vector& M_sub_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
00496 template <class E> Vector& M_mul_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
00497 template <class E> Vector& M_div_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
00498 template <class E> Vector& M_mod_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
00499 template <class E> Vector& M_xor_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
00500 template <class E> Vector& M_and_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
00501 template <class E> Vector& M_or_eq (const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
00502 template <class E> Vector& M_shl_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
00503 template <class E> Vector& M_shr_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
00504
00505 public:
00506 template <class T2> Vector& alias_assign(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
00507 template <class T2> Vector& alias_add_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
00508 template <class T2> Vector& alias_sub_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
00509 template <class T2> Vector& alias_mul_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
00510 template <class T2> Vector& alias_div_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
00511
00512 template <class E> Vector& alias_assign(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
00513 template <class E> Vector& alias_add_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
00514 template <class E> Vector& alias_sub_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
00515 template <class E> Vector& alias_mul_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
00516 template <class E> Vector& alias_div_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
00517
00518 public:
00520 struct Info : public TvmetBase<Info> {
00521 std::ostream& print_xpr(std::ostream& os) const {
00522 os << "Vector<T=" << typeid(value_type).name()
00523 << ", Sz=" << Size << ">";
00524 return os;
00525 }
00526 };
00527
00529 static Info info() { return Info(); }
00530
00532 std::ostream& print_xpr(std::ostream& os, std::size_t l=0) const;
00533
00535 std::ostream& print_on(std::ostream& os) const;
00536
00537 private:
00540 #if defined(TVMET_DYNAMIC_MEMORY)
00541 value_type* m_data;
00542 #else
00543 value_type m_data[Size];
00544 #endif
00545 };
00546
00547
00548 }
00549
00550 #include <tvmet/VectorImpl.h>
00551 #include <tvmet/VectorFunctions.h>
00552 #include <tvmet/VectorBinaryFunctions.h>
00553 #include <tvmet/VectorUnaryFunctions.h>
00554 #include <tvmet/VectorOperators.h>
00555 #include <tvmet/VectorEval.h>
00556 #include <tvmet/AliasProxy.h>
00557
00558 #endif // TVMET_VECTOR_H
00559
00560
00561
00562
00563