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:
00438 #if defined(TVMET_DYNAMIC_MEMORY)
00439
00443 Vector& operator=(const Vector& rhs) {
00444 rhs.assign_to(*this, Fcnl_assign<value_type, value_type>());
00445 return *this;
00446 }
00447 #endif
00448
00451 template<class T2>
00452 Vector& operator=(const Vector<T2, Size>& rhs) {
00453 rhs.assign_to(*this, Fcnl_assign<value_type, T2>());
00454 return *this;
00455 }
00456
00458 template<class E>
00459 Vector& operator=(const XprVector<E, Size>& rhs) {
00460 rhs.assign_to(*this, Fcnl_assign<value_type, typename E::value_type>());
00461 return *this;
00462 }
00463
00464 private:
00465 template<class Obj, std::size_t LEN> friend class CommaInitializer;
00466
00470 Vector& assign_value(value_type rhs) {
00471 typedef XprLiteral<value_type> expr_type;
00472 *this = XprVector<expr_type, Size>(expr_type(rhs));
00473 return *this;
00474 }
00475
00476 public:
00477
00478 Vector& operator+=(value_type) TVMET_CXX_ALWAYS_INLINE;
00479 Vector& operator-=(value_type) TVMET_CXX_ALWAYS_INLINE;
00480 Vector& operator*=(value_type) TVMET_CXX_ALWAYS_INLINE;
00481 Vector& operator/=(value_type) TVMET_CXX_ALWAYS_INLINE;
00482
00483 Vector& operator%=(std::size_t) TVMET_CXX_ALWAYS_INLINE;
00484 Vector& operator^=(std::size_t) TVMET_CXX_ALWAYS_INLINE;
00485 Vector& operator&=(std::size_t) TVMET_CXX_ALWAYS_INLINE;
00486 Vector& operator|=(std::size_t) TVMET_CXX_ALWAYS_INLINE;
00487 Vector& operator<<=(std::size_t) TVMET_CXX_ALWAYS_INLINE;
00488 Vector& operator>>=(std::size_t) TVMET_CXX_ALWAYS_INLINE;
00489
00490 public:
00491
00492 template <class T2> Vector& M_add_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
00493 template <class T2> Vector& M_sub_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
00494 template <class T2> Vector& M_mul_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
00495 template <class T2> Vector& M_div_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
00496 template <class T2> Vector& M_mod_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
00497 template <class T2> Vector& M_xor_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
00498 template <class T2> Vector& M_and_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
00499 template <class T2> Vector& M_or_eq (const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
00500 template <class T2> Vector& M_shl_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
00501 template <class T2> Vector& M_shr_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
00502
00503 public:
00504
00505 template <class E> Vector& M_add_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
00506 template <class E> Vector& M_sub_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
00507 template <class E> Vector& M_mul_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
00508 template <class E> Vector& M_div_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
00509 template <class E> Vector& M_mod_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
00510 template <class E> Vector& M_xor_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
00511 template <class E> Vector& M_and_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
00512 template <class E> Vector& M_or_eq (const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
00513 template <class E> Vector& M_shl_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
00514 template <class E> Vector& M_shr_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
00515
00516 public:
00517 template <class T2> Vector& alias_assign(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
00518 template <class T2> Vector& alias_add_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
00519 template <class T2> Vector& alias_sub_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
00520 template <class T2> Vector& alias_mul_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
00521 template <class T2> Vector& alias_div_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
00522
00523 template <class E> Vector& alias_assign(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
00524 template <class E> Vector& alias_add_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
00525 template <class E> Vector& alias_sub_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
00526 template <class E> Vector& alias_mul_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
00527 template <class E> Vector& alias_div_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
00528
00529 public:
00531 struct Info : public TvmetBase<Info> {
00532 std::ostream& print_xpr(std::ostream& os) const {
00533 os << "Vector<T=" << typeid(value_type).name()
00534 << ", Sz=" << Size << ">";
00535 return os;
00536 }
00537 };
00538
00540 static Info info() { return Info(); }
00541
00543 std::ostream& print_xpr(std::ostream& os, std::size_t l=0) const;
00544
00546 std::ostream& print_on(std::ostream& os) const;
00547
00548 private:
00551 #if defined(TVMET_DYNAMIC_MEMORY)
00552 value_type* m_data;
00553 #else
00554 value_type m_data[Size];
00555 #endif
00556 };
00557
00558
00559 }
00560
00561 #include <tvmet/VectorImpl.h>
00562 #include <tvmet/VectorFunctions.h>
00563 #include <tvmet/VectorBinaryFunctions.h>
00564 #include <tvmet/VectorUnaryFunctions.h>
00565 #include <tvmet/VectorOperators.h>
00566 #include <tvmet/VectorEval.h>
00567 #include <tvmet/AliasProxy.h>
00568
00569 #endif // TVMET_VECTOR_H
00570
00571
00572
00573
00574