internal/vector.hh

00001 //-*- c++ -*-
00002 //
00003 // Copyright (C) 2009 Tom Drummond (twd20@cam.ac.uk),
00004 // Ed Rosten (er258@cam.ac.uk)
00005 //
00006 // This file is part of the TooN Library.  This library is free
00007 // software; you can redistribute it and/or modify it under the
00008 // terms of the GNU General Public License as published by the
00009 // Free Software Foundation; either version 2, or (at your option)
00010 // 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
00015 // GNU General Public License for more details.
00016 
00017 // You should have received a copy of the GNU General Public License along
00018 // with this library; see the file COPYING.  If not, write to the Free
00019 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
00020 // USA.
00021 
00022 // As a special exception, you may use this file as part of a free software
00023 // library without restriction.  Specifically, if other files instantiate
00024 // templates or use macros or inline functions from this file, or you compile
00025 // this file and link it with other files to produce an executable, this
00026 // file does not by itself cause the resulting executable to be covered by
00027 // the GNU General Public License.  This exception does not however
00028 // invalidate any other reasons why the executable file might be covered by
00029 // the GNU General Public License.
00030 
00031 
00032 
00033 namespace TooN {
00034 
00035 
00127 template<int Size=Dynamic, typename Precision=DefaultPrecision, typename Base=Internal::VBase>
00128 struct Vector : public Base::template VLayout<Size, Precision> {
00129 public:
00130   // sneaky hack: only one of these constructors will work with any given base
00131   // class but they don't generate errors unless the user tries to use one of them
00132   // although the error message may be less than helpful - maybe this can be changed?
00133 
00135 
00136 
00142     inline Vector(){}
00143 
00147     inline Vector(int size_in) : Base::template VLayout<Size, Precision>(size_in) {}
00148 
00155     inline Vector(Precision* data) : Base::template VLayout<Size, Precision> (data) {}
00156 
00157 
00164     inline Vector(Precision* data, int size_in) : Base::template VLayout<Size, Precision> (data, size_in) {}
00165 
00167     inline Vector(Precision* data_in, int size_in, int stride_in, Internal::Slicing)
00168   : Base::template VLayout<Size, Precision>(data_in, size_in, stride_in) {}
00169     
00170     using Base::template VLayout<Size, Precision>::size;
00171 
00177     template <class Op>
00178     inline Vector(const Operator<Op>& op)
00179         : Base::template VLayout<Size, Precision> (op)
00180     {
00181         op.eval(*this);
00182     }
00183 
00184     // Copy construction is a very special case. Copy construction goes all the
00185     // way down to the bottom. GenericVBase has no idea how to copy itself.
00186     // However, the underlying allocator objects do.  In the case of static sized
00187     // objects, C++ automatically copies the data.  For slice objects, C++ copies
00188     // all parts (pointer and size), which is correct.  For dynamically sized
00189     // non-slice objects the copying has to be done by hand.
00190     
00191     // inline Vector(const Vector&from);
00192 
00194     template<int Size2, typename Precision2, typename Base2>
00195     inline Vector(const Vector<Size2,Precision2,Base2>& from):
00196         Base::template VLayout<Size, Precision>(from.size()) {
00197         operator=(from);
00198     }
00199 
00201 
00202 #ifdef DOXYGEN_INCLUDE_ONLY_FOR_DOCS
00203 
00206 
00214     Precision& operator[] (int i);
00215 
00217     const Precision& operator[] (int i) const;
00218 
00220 
00221 #endif
00222 
00225 
00227     inline Vector& operator= (const Vector& from){
00228         SizeMismatch<Size,Size>::test(size(), from.size());
00229         const int s=size();
00230         for(int i=0; i<s; i++){
00231             (*this)[i]=from[i];
00232         }
00233         return *this;
00234     }
00235 
00237     template<int Size2, typename Precision2, typename Base2>
00238     Vector<Size,Precision,Base >& operator= (const Vector<Size2, Precision2, Base2>& from){
00239         SizeMismatch<Size,Size2>::test(size(), from.size());
00240         const int s=size();
00241         for(int i=0; i<s; i++){
00242             (*this)[i]=from[i];
00243         }
00244         return *this;
00245     }
00246 
00248     template <class Op>
00249     inline Vector & operator=(const Operator<Op>& op){
00250         op.eval(*this);
00251         return *this;
00252     }
00254 
00257 
00259     Vector& operator/=(const Precision& rhs) {
00260         for(int i=0; i<size(); i++)
00261             (*this)[i]/=rhs;
00262         return *this;
00263     }
00264     
00266     Vector& operator*=(const Precision& rhs) {
00267         for(int i=0; i<size(); i++)
00268             (*this)[i]*=rhs;
00269         return *this;
00270     }
00271     
00273     template<int Size2, class Precision2, class Base2>
00274     Vector& operator+=(const Vector<Size2, Precision2, Base2>& rhs) {
00275         SizeMismatch<Size,Size2>::test(size(),rhs.size());
00276         for(int i=0; i<size(); i++)
00277             (*this)[i]+=rhs[i];
00278         return *this;
00279     }
00280     
00288     template<class Op>
00289     Vector& operator+=(const Operator<Op>& op)
00290     {
00291         op.plusequals(*this);
00292         return *this;
00293     }       
00294 
00295     template<class Op>
00296     Vector& operator-=(const Operator<Op>& op)
00297     {
00298         op.minusequals(*this);
00299         return *this;
00300     }       
00301 
00303     template<int Size2, class Precision2, class Base2>
00304     Vector& operator-=(const Vector<Size2, Precision2, Base2>& rhs) {
00305         SizeMismatch<Size,Size2>::test(size(),rhs.size());
00306         for(int i=0; i<size(); i++)
00307             (*this)[i]-=rhs[i];
00308         return *this;
00309     }
00310 
00312 
00315 
00317     template<int Size2, class Precision2, class Base2>
00318     bool operator==(const Vector<Size2, Precision2, Base2>& rhs) {
00319         SizeMismatch<Size,Size2>::test(size(),rhs.size());
00320         for(int i=0; i<size(); i++)
00321           if((*this)[i]!=rhs[i])
00322             return 0;
00323         return 1;
00324     }
00325 
00327     template<int Size2, class Precision2, class Base2>
00328     bool operator!=(const Vector<Size2, Precision2, Base2>& rhs) {
00329         SizeMismatch<Size,Size2>::test(size(),rhs.size());
00330         for(int i=0; i<size(); i++)
00331           if((*this)[i]!=rhs[i])
00332             return 1;
00333         return 0;
00334     }
00335 
00337 
00340 
00342     Vector& ref()
00343     {
00344         return *this;
00345     }
00346 
00347 #ifdef DOXYGEN_INCLUDE_ONLY_FOR_DOCS
00348 
00350     int size() const;
00351 
00353 
00355 
00356 
00364     Matrix<1, Size, Precision> as_row();
00365   
00374     Matrix<Size, 1, Precision> as_col();
00375   
00385     DiagonalMatrix<Size,Precision> as_diagonal();
00386 
00396     template<Start, Length>
00397     const Vector<Length,Precision>& slice() const;
00398   
00410     template<Start, Length>
00411     Vector<Length,Precision>& slice();
00412   
00423     template<Start, Length>
00424     const Vector<Length,Precision>& slice() const;
00425   
00437     template<Start, Length>
00438     Vector<Length,Precision>& slice();
00440 
00441 #endif
00442 
00443 };
00444 
00445 }

Generated on Thu May 7 20:28:40 2009 for TooN by  doxygen 1.5.3