TooN 2.1
internal/vbase.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 namespace TooN {
00032 
00033 namespace Internal{
00034 template<int Size, class Precision, int Stride, class Mem> struct GenericVBase;
00035 
00036 ////////////////////////////////////////////////////////////////////////////////
00037 //
00038 // Slice holding class
00039 //
00040 struct Default{};
00041 
00042 template<int Stride, class Ptr=Default, class CPtr=Default, class Ref=Default, class CRef=Default>
00043 struct SliceVBase {
00044 
00045     // this class is really just a typedef
00046     template<int Size, typename Precision>
00047     struct VLayout
00048         : public GenericVBase<Size, Precision, Stride, VectorSlice<Size, Precision, Ptr, CPtr, Ref, CRef> > {
00049         typedef typename VectorSlice<Size, Precision, Ptr, CPtr, Ref, CRef>::PointerType PointerType;
00050     
00051         VLayout(PointerType d, int length, int stride)
00052             :GenericVBase<Size, Precision, Stride, VectorSlice<Size, Precision, Ptr, CPtr, Ref, CRef> >(d, length, stride){
00053         }
00054 
00055         template<class Op>
00056         VLayout(const Operator<Op>& op)
00057             :GenericVBase<Size, Precision, Stride, VectorSlice<Size, Precision> >(op) {}
00058     };
00059 
00060 };
00061 
00062 template<int Stride>
00063 struct SliceVBase<Stride, Default, Default, Default, Default> {
00064 
00065     // this class is really just a typedef
00066     template<int Size, typename Precision>
00067     struct VLayout
00068         : public GenericVBase<Size, Precision, Stride, VectorSlice<Size, Precision> > {
00069 
00070         typedef typename VectorSlice<Size, Precision>::PointerType PointerType;
00071     
00072         VLayout(PointerType d, int length, int stride)
00073             :GenericVBase<Size, Precision, Stride, VectorSlice<Size, Precision> >(d, length, stride){
00074         }
00075 
00076         template<class Op>
00077         VLayout(const Operator<Op>& op)
00078             :GenericVBase<Size, Precision, Stride, VectorSlice<Size, Precision> >(op) {}
00079     };
00080 
00081 };
00082 
00083 ////////////////////////////////////////////////////////////////////////////////
00084 //
00085 // Classes for Vectors owning memory
00086 //
00087 
00088 struct VBase {
00089 
00090     // this class is really just a typedef
00091     template<int Size, class Precision>
00092     struct VLayout 
00093         : public GenericVBase<Size, Precision, 1, VectorAlloc<Size, Precision> > {
00094     
00095         VLayout(){}
00096 
00097         VLayout(int s)
00098             :GenericVBase<Size, Precision, 1, VectorAlloc<Size, Precision> >(s)
00099         {}
00100 
00101         template<class Op>
00102         VLayout(const Operator<Op>& op)
00103             :GenericVBase<Size, Precision, 1, VectorAlloc<Size, Precision> >(op) {}
00104     };
00105 };
00106 
00107 ////////////////////////////////////////////////////////////////////////////////
00108 //
00109 // Generic implementation
00110 //
00111 
00112 template<int Size, typename Precision, int Stride, typename Mem> struct GenericVBase: public Mem, public StrideHolder<Stride>
00113 {   
00114     int stride() const{
00115         return StrideHolder<Stride>::stride();
00116     }
00117 
00118     //Optional constuctors
00119     GenericVBase(){}
00120 
00121     GenericVBase(int s)
00122     :Mem(s)
00123     {}
00124 
00125     typedef typename Mem::PointerType PointerType;
00126     typedef typename Mem::ConstPointerType ConstPointerType;
00127     typedef typename Mem::ReferenceType ReferenceType;
00128     typedef typename Mem::ConstReferenceType ConstReferenceType;
00129 
00130     GenericVBase(PointerType d, int length, int stride)
00131     :Mem(d, length),StrideHolder<Stride>(stride){
00132     }
00133     
00134     template<class Op>
00135     GenericVBase(const Operator<Op> & op) : Mem(op), StrideHolder<Stride>(op) {}
00136 
00137     using Mem::data;
00138     using Mem::size;
00139 
00140     ReferenceType operator[](int i) {
00141         Internal::check_index(size(), i);
00142         return data()[i * stride()];
00143     }
00144 
00145     ConstReferenceType operator[](int i) const {
00146         Internal::check_index(size(), i);
00147         return data()[i * stride()];
00148     }
00149 
00150     typedef SliceVBase<Stride, PointerType, ConstPointerType, ReferenceType, ConstReferenceType> SliceBase;
00151     typedef SliceVBase<Stride, ConstPointerType, ConstPointerType, ConstReferenceType, ConstReferenceType> ConstSliceBase;
00152 
00153 
00154     //Completely generic Vector slice operations below:
00155     template<int Start, int Length> 
00156     Vector<Length, Precision, SliceBase> slice(int start, int length){
00157         Internal::CheckSlice<Size, Start, Length>::check(size(), start, length);    
00158         return Vector<Length, Precision, SliceBase>(data() + stride() * (Start==Dynamic?start:Start), Length==Dynamic?length:Length, stride(), Slicing());
00159     }
00160 
00161     template<int Start, int Length> 
00162     const Vector<Length, const Precision, ConstSliceBase> slice(int start, int length) const{
00163         Internal::CheckSlice<Size, Start, Length>::check(size(), start, length);    
00164         return Vector<Length, const Precision, ConstSliceBase>(data() + stride() * (Start==Dynamic?start:Start), Length==Dynamic?length:Length, stride(), Slicing());
00165     }
00166 
00167     
00168 
00169     //Special case slice operations
00170     template<int Start, int Length> Vector<Length, Precision, SliceBase> slice(){
00171         Internal::CheckSlice<Size, Start, Length>::check();
00172         return slice<Start, Length>(Start, Length);
00173     }
00174 
00175     template<int Start, int Length> const Vector<Length, const Precision, ConstSliceBase> slice() const {
00176         Internal::CheckSlice<Size, Start, Length>::check();
00177         return slice<Start, Length>(Start, Length);
00178     }
00179 
00180     Vector<Dynamic, Precision, SliceBase> slice(int start, int length){
00181         return slice<Dynamic, Dynamic>(start, length);
00182     }
00183 
00184     const Vector<Dynamic, const Precision, ConstSliceBase> slice(int start, int length) const{
00185         return slice<Dynamic, Dynamic>(start, length);
00186     }
00187         
00188     //Other slices below
00189     const Matrix<1, Size, const Precision, Slice<1,Stride> > as_row() const{
00190         return Matrix<1, Size, const Precision, Slice<1,Stride> >(data(), 1, size(), 1, stride(), Slicing());
00191     }
00192 
00193     Matrix<1, Size, Precision, Slice<1,Stride> > as_row(){
00194         return Matrix<1, Size, Precision, Slice<1,Stride> >(data(), 1, size(), 1, stride(), Slicing());
00195     }
00196 
00197     const Matrix<Size, 1, const Precision, Slice<Stride,1> > as_col() const{
00198         return Matrix<Size, 1, const Precision, Slice<Stride,1> >(data(), size(), 1, stride(), 1, Slicing());
00199     }
00200 
00201     Matrix<Size, 1, Precision, Slice<Stride,1> > as_col(){
00202         return Matrix<Size, 1, Precision, Slice<Stride,1> >(data(), size(), 1, stride(), 1, Slicing());
00203     }
00204 
00205     typedef Vector<Size, Precision, SliceBase> as_slice_type;
00206     
00207     Vector<Size, Precision, SliceBase> as_slice(){                 
00208         return Vector<Size, Precision, SliceBase>(data(), size(), stride(), Slicing());         
00209     }
00210 
00211     const Vector<Size, const Precision, ConstSliceBase> as_slice() const {                 
00212         return Vector<Size, const Precision, ConstSliceBase>(data(), size(), stride(), Slicing());         
00213     }
00214 
00215     DiagonalMatrix<Size,Precision, SliceBase> as_diagonal() {
00216         return DiagonalMatrix<Size, Precision, SliceBase> (data(), size(), stride(), Slicing());
00217     }
00218 
00219     const DiagonalMatrix<Size,const Precision, ConstSliceBase> as_diagonal() const {
00220         return DiagonalMatrix<Size, const Precision, ConstSliceBase> (data(), size(), stride(), Slicing());
00221     }
00222 
00223 };
00224 
00225 }
00226 
00227 }