TooN 2.1
|
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 }