SourceForge Logo Tiny Vector Matrix library using Expression Templates Sourceforge Project Page

include/tvmet/Vector.h

Go to the documentation of this file.
00001 /*
00002  * Tiny Vector Matrix Library
00003  * Dense Vector Matrix Libary of Tiny size using Expression Templates
00004  *
00005  * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020  *
00021  * $Id: Vector.h,v 1.48 2007-06-23 15:58:58 opetzold Exp $
00022  */
00023 
00024 #ifndef TVMET_VECTOR_H
00025 #define TVMET_VECTOR_H
00026 
00027 #include <iterator>         // reverse_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 /* forwards */
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: // types
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: // access operators
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: // debugging Xpr parse tree
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: // STL  interface
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: // access operators
00380   value_type* _tvmet_restrict data() { return m_data; }
00381   const value_type* _tvmet_restrict data() const { return m_data; }
00382 
00383 public: // index access operators
00384   value_type& _tvmet_restrict operator()(std::size_t i) {
00385     // Note: g++-2.95.3 does have problems on typedef reference
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     // Note: g++-2.95.3 does have problems on typedef reference
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: // ET interface
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:   // assign operations
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: // math operators with scalars
00466   // NOTE: this meaning is clear - element wise ops even if not in ns element_wise
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: // math assign operators with vectors
00480   // NOTE: access using the operators in ns element_wise, since that's what is does
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: // math operators with expressions
00493   // NOTE: access using the operators in ns element_wise, since that's what is does
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: // aliased math operators with expressions, used with proxy
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: // io
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 } // namespace tvmet
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 // Local Variables:
00561 // mode:C++
00562 // tab-width:8
00563 // End:

Author: