00001 #pragma ident "$Id: VectorBase.hpp 3140 2012-06-18 15:03:02Z susancummins $"
00002
00003
00004
00010 #ifndef GPSTK_VECTOR_BASE_HPP
00011 #define GPSTK_VECTOR_BASE_HPP
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <valarray>
00036 #include "Exception.hpp"
00037
00038 #include "MathBase.hpp"
00039
00040 namespace gpstk
00041 {
00044
00047 NEW_EXCEPTION_CLASS(VectorException, gpstk::Exception);
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00085 template <class T, class BaseClass>
00086 class ConstVectorBase
00087 {
00088 public:
00090 explicit ConstVectorBase() {}
00091
00093 size_t size() const
00094 { return static_cast<const BaseClass*>(this)->size(); }
00096 T operator[] (size_t i) const
00097 { return constVectorRef(i); }
00099 T operator() (size_t i) const
00100 { return constVectorRef(i); }
00101
00102 protected:
00104 inline T constVectorRef(size_t i) const
00105 throw(VectorException)
00106 {
00107 const BaseClass& b = static_cast<const BaseClass&>(*this);
00108 #ifdef RANGECHECK
00109 if (i >= b.size())
00110 {
00111 VectorException e("Invalid ConstVectorBase index");
00112 GPSTK_THROW(e);
00113 }
00114 #endif
00115 return b[i];
00116 }
00117 };
00118
00122 class RefVectorBaseHelper
00123 {
00124 public:
00127 static double zeroTolerance;
00128 };
00129
00133 template <class T, class BaseClass>
00134 class RefVectorBase : public ConstVectorBase<T, BaseClass>,
00135 public RefVectorBaseHelper
00136 {
00137 public:
00139 explicit RefVectorBase() {}
00141 T& operator[] (size_t i)
00142 { return vecRef(i); }
00144 T& operator() (size_t i)
00145 { return vecRef(i); }
00148 BaseClass& zeroize()
00149 {
00150 BaseClass& me = static_cast<BaseClass&>(*this);
00151 size_t i;
00152 for (i = 0; i < me.size(); i++)
00153 if (ABS(me[i]) < zeroTolerance)
00154 me[i] = T(0);
00155 return me;
00156 }
00157
00158 #define VecBaseArrayAssignMacroDontCheckRange(func) \
00159 BaseClass& me = static_cast<BaseClass&>(*this); \
00160 size_t i; for (i=0; i < me.size(); i++) { \
00161 me[i] func x[i]; \
00162 } \
00163 return me;
00164
00165 #ifdef RANGECHECK
00166 #define VecBaseArrayAssignMacro(func) \
00167 BaseClass& me = static_cast<BaseClass&>(*this); \
00168 if (x.size() != me.size()) \
00169 { \
00170 VectorException e("Unequal lengths for vectors"); \
00171 GPSTK_THROW(e); \
00172 } \
00173 size_t i; for (i=0; i < me.size(); i++) me[i] func x[i]; \
00174 return me;
00175 #else
00176 #define VecBaseArrayAssignMacro(func) \
00177 VecBaseArrayAssignMacroDontCheckRange(func)
00178 #endif
00179
00180 #define VecBaseAtomicAssignMacro(func) \
00181 BaseClass& me = static_cast<BaseClass&>(*this); \
00182 size_t i; for (i=0; i < me.size(); i++) me[i] func x; \
00183 return me;
00184
00185 #define VecBaseNewAssignOperator(funcName, op) \
00186 \
00187 template <class E> BaseClass& funcName(const ConstVectorBase<T, E>& x) \
00188 { VecBaseArrayAssignMacro(op) } \
00189 \
00190 BaseClass& funcName(const std::valarray<T>& x) \
00191 { VecBaseArrayAssignMacro(op) } \
00192 \
00193 BaseClass& funcName(const T* x) \
00194 { VecBaseArrayAssignMacroDontCheckRange(op) } \
00195 \
00196 BaseClass& funcName(T x) \
00197 { VecBaseAtomicAssignMacro(op) }
00198
00204 VecBaseNewAssignOperator(assignFrom, =);
00205 VecBaseNewAssignOperator(operator+=, +=);
00206 VecBaseNewAssignOperator(operator-=, -=);
00207 VecBaseNewAssignOperator(operator*=, *=);
00208 VecBaseNewAssignOperator(operator/=, /=);
00209
00210
00211
00212
00213
00214
00215
00216
00217
00219 const BaseClass operator-() const
00220 {
00221 const T x=T(-1);
00222 BaseClass me = static_cast<BaseClass>(*this);
00223 size_t i;
00224 for (i=0; i < me.size(); i++) me(i) *= x;
00225 return me;
00226 }
00227
00228 protected:
00230 inline T& vecRef(size_t i)
00231 throw(VectorException)
00232 {
00233 BaseClass& b = static_cast<BaseClass&>(*this);
00234 #ifdef RANGECHECK
00235 if (i >= b.size())
00236 {
00237 VectorException e("Invalid VectorBase index");
00238 GPSTK_THROW(e);
00239 }
00240 #endif
00241 return b[i];
00242 }
00243 };
00244
00248 template <class BaseClass>
00249 class VectorSliceBase
00250 {
00251 public:
00253 explicit VectorSliceBase() {}
00254
00256 size_t size() const
00257 { return static_cast<const BaseClass*>(this)->size(); }
00259 size_t start() const
00260 { return static_cast<const BaseClass*>(this)->start(); }
00262 size_t stride() const
00263 { return static_cast<const BaseClass*>(this)->stride(); }
00264
00265 protected:
00267 inline void vecSliceCheck(size_t sourceSize) const
00268 throw(VectorException)
00269 {
00270 #ifdef RANGECHECK
00271
00272 if ( (start() >= sourceSize) ||
00273 ((start() + (size() - 1) * stride()) >= sourceSize) )
00274 {
00275 VectorException e("Invalid range for slice");
00276 GPSTK_THROW(e);
00277 }
00278 #endif
00279 }
00280 };
00281
00286 template <class T, class BaseClass>
00287 class ConstVectorSliceBase : public VectorSliceBase<BaseClass>,
00288 public ConstVectorBase<T, BaseClass>
00289 {
00290 public:
00291 explicit ConstVectorSliceBase() {}
00292 };
00293
00298 template <class T, class BaseClass>
00299 class RefVectorSliceBase : public VectorSliceBase<BaseClass>,
00300 public RefVectorBase<T, BaseClass>
00301 {
00302 public:
00303 explicit RefVectorSliceBase() {}
00304 };
00305
00307
00308 }
00309
00310 #include "VectorBaseOperators.hpp"
00311
00312 #endif //GPSTK_VECTOR_BASE_HPP