00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef Physical_Qty_H
00010 #define Physical_Qty_H
00011 #include "TemplateTools.h"
00012
00023 namespace ThePEG {
00024
00026 struct ZeroUnit {
00028 operator double() const { return 0.0; }
00029 };
00030
00032 const ZeroUnit ZERO = ZeroUnit();
00033
00035
00036
00039 template <int M, int II>
00040 struct QtyHelper
00041 {
00043 static const int I = -999999;
00044 };
00045
00049 template <int II>
00050 struct QtyHelper<0,II>
00051 {
00053 static const int I = II;
00054 };
00055
00059 template <int II, int DI, int DI2>
00060 struct QtyInt
00061 {
00063 static const int I = QtyHelper<(DI2*II)%DI,(DI2*II)/DI>::I;
00064 };
00066
00079 template<int L, int E, int Q, int DL = 1, int DE = 1, int DQ = 1>
00080 class Qty
00081 {
00082 private:
00084 Qty(double val) : rawValue_(val) {}
00085
00086 public:
00088 typedef Qty<2*L,2*E,2*Q,DL,DE,DQ> Squared;
00089
00091 static Qty<L,E,Q,DL,DE,DQ> baseunit()
00092 {
00093 return Qty<L,E,Q,DL,DE,DQ>(1.0);
00094 }
00095
00097 Qty() : rawValue_(0.0) {}
00098
00100 Qty(ZeroUnit) : rawValue_(0.0) {}
00101
00103 template <int DL2, int DE2, int DQ2>
00104 Qty(const Qty<QtyInt<L,DL,DL2>::I,
00105 QtyInt<E,DE,DE2>::I,
00106 QtyInt<Q,DQ,DQ2>::I,
00107 DL2,DE2,DQ2> & q)
00108 : rawValue_(q.rawValue()) {}
00109
00111 double rawValue() const { return rawValue_; }
00112
00114 Qty<L,E,Q,DL,DE,DQ> & operator*=(double x) { rawValue_ *= x; return *this; }
00115
00117 Qty<L,E,Q,DL,DE,DQ> & operator/=(double x) { rawValue_ /= x; return *this; }
00118
00120 template <int DL2, int DE2, int DQ2>
00121 Qty<L,E,Q,DL,DE,DQ> &
00122 operator+=(const Qty<QtyInt<L,DL,DL2>::I,
00123 QtyInt<E,DE,DE2>::I,
00124 QtyInt<Q,DQ,DQ2>::I,
00125 DL2,DE2,DQ2> x)
00126 {
00127 rawValue_ += x.rawValue();
00128 return *this;
00129 }
00130
00132 template <int DL2, int DE2, int DQ2>
00133 Qty<L,E,Q,DL,DE,DQ> &
00134 operator-=(const Qty<QtyInt<L,DL,DL2>::I,
00135 QtyInt<E,DE,DE2>::I,
00136 QtyInt<Q,DQ,DQ2>::I,
00137 DL2,DE2,DQ2> x)
00138 {
00139 rawValue_ -= x.rawValue();
00140 return *this;
00141 }
00142
00143 private:
00145 double rawValue_;
00146 };
00147
00149 template<int DL, int DE, int DQ>
00150 class Qty<0,0,0,DL,DE,DQ>
00151 {
00152 public:
00154 typedef Qty<0,0,0,DL,DE,DQ> Squared;
00155
00157 static double baseunit() {
00158 return 1.0;
00159 }
00160
00162 Qty(ZeroUnit) : rawValue_(0.0) {}
00163
00165 Qty(double x = 0.0) : rawValue_(x) {}
00166
00168 template <int DL2, int DE2, int DQ2>
00169 Qty(const Qty<0,0,0,DL2,DE2,DQ2> & q) : rawValue_(q.rawValue()) {}
00170
00172 double rawValue() const { return rawValue_; }
00173
00175 operator double() const { return rawValue_; }
00176
00178 Qty<0,0,0,DL,DE,DQ> & operator*=(double x) { rawValue_ *= x; return *this; }
00179
00181 Qty<0,0,0,DL,DE,DQ> & operator/=(double x) { rawValue_ /= x; return *this; }
00182
00184 template <int DL2, int DE2, int DQ2>
00185 Qty<0,0,0,DL,DE,DQ> & operator+=(const Qty<0,0,0,DL2,DE2,DQ2> x) {
00186 rawValue_ += x.rawValue();
00187 return *this;
00188 }
00189
00191 template <int DL2, int DE2, int DQ2>
00192 Qty<0,0,0,DL,DE,DQ> & operator-=(const Qty<0,0,0,DL2,DE2,DQ2> x) {
00193 rawValue_ -= x.rawValue();
00194 return *this;
00195 }
00196
00198 Qty<0,0,0,DL,DE,DQ> & operator+=(double x) {
00199 rawValue_ += x;
00200 return *this;
00201 }
00202
00204 Qty<0,0,0,DL,DE,DQ> & operator-=(double x) {
00205 rawValue_ -= x;
00206 return *this;
00207 }
00208
00209 private:
00211 double rawValue_;
00212 };
00213
00215
00216
00221 template <typename T, typename U>
00222 struct BinaryOpTraits;
00223
00226 template<int L1, int L2, int E1, int E2, int Q1, int Q2,
00227 int DL1, int DL2, int DE1, int DE2, int DQ1, int DQ2>
00228 struct BinaryOpTraits<Qty<L1,E1,Q1,DL1,DE1,DQ1>,
00229 Qty<L2,E2,Q2,DL2,DE2,DQ2> > {
00232 typedef Qty<L1*DL2+L2*DL1,E1*DE2+E2*DE1,Q1*DQ2+Q2*DQ1,
00233 DL1*DL2,DE1*DE2,DQ1*DQ2> MulT;
00236 typedef Qty<L1*DL2-L2*DL1,E1*DE2-E2*DE1,Q1*DQ2-Q2*DQ1,
00237 DL1*DL2,DE1*DE2,DQ1*DQ2> DivT;
00238 };
00239
00240
00241 template<int L1, int E1, int Q1, int DL1, int DE1, int DQ1>
00242 struct BinaryOpTraits<Qty<L1,E1,Q1,DL1,DE1,DQ1>,
00243 Qty<L1,E1,Q1,DL1,DE1,DQ1> > {
00246 typedef Qty<2*L1,2*E1,2*Q1,
00247 DL1,DE1,DQ1> MulT;
00250 typedef double DivT;
00251 };
00252
00256 template<int L1, int E1, int Q1, int DL1, int DE1, int DQ1>
00257 struct BinaryOpTraits<double,
00258 Qty<L1,E1,Q1,DL1,DE1,DQ1> > {
00261 typedef Qty<L1,E1,Q1,
00262 DL1,DE1,DQ1> MulT;
00265 typedef Qty<-L1,-E1,-Q1,
00266 DL1,DE1,DQ1> DivT;
00267 };
00268
00272 template<int L1, int E1, int Q1, int DL1, int DE1, int DQ1>
00273 struct BinaryOpTraits<Qty<L1,E1,Q1,DL1,DE1,DQ1>,
00274 double> {
00277 typedef Qty<L1,E1,Q1,
00278 DL1,DE1,DQ1> MulT;
00281 typedef Qty<L1,E1,Q1,
00282 DL1,DE1,DQ1> DivT;
00283 };
00285
00287
00288
00289 template <int L, int E, int Q, int DL, int DE, int DQ>
00290 struct TypeTraits<Qty<L,E,Q,DL,DE,DQ> >
00291 {
00293 enum { hasDimension = true };
00295 typedef DimensionT DimType;
00296 static const Qty<L,E,Q,DL,DE,DQ> baseunit;
00297 };
00298
00300 template <int L, int E, int Q, int DL, int DE, int DQ>
00301 const Qty<L,E,Q,DL,DE,DQ>
00302 TypeTraits<Qty<L,E,Q,DL,DE,DQ> >::baseunit = Qty<L,E,Q,DL,DE,DQ>::baseunit();
00303
00304
00306 template <int DL, int DE, int DQ>
00307 struct TypeTraits<Qty<0,0,0,DL,DE,DQ> >
00308 {
00310 enum { hasDimension = false };
00312 typedef StandardT DimType;
00313 static const double baseunit;
00314 };
00315
00317 template <int DL, int DE, int DQ>
00318 const double
00319 TypeTraits<Qty<0,0,0,DL,DE,DQ> >::baseunit = 1.0;
00321
00324 }
00325
00326 #endif