File indexing completed on 2026-08-06 09:38:20
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef Physical_Qty_H
0010 #define Physical_Qty_H
0011 #include "TemplateTools.h"
0012 #include <sstream>
0013 #include <ratio>
0014 #include <type_traits>
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 namespace ThePEG {
0027
0028
0029 struct ZeroUnit {
0030
0031 constexpr operator double() const { return 0.0; }
0032 };
0033
0034
0035 constexpr ZeroUnit ZERO = ZeroUnit();
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051 template <typename L, typename E, typename T>
0052 class Qty;
0053
0054 template <typename T, typename U>
0055 struct qty_equal {
0056 static constexpr bool value = false;
0057 };
0058
0059 template<typename L1, typename L2, typename E1, typename E2, typename Q1, typename Q2>
0060 struct qty_equal<Qty<L1,E1,Q1>, Qty<L2,E2,Q2>> {
0061 static constexpr bool value
0062 = std::ratio_equal<L1,L2>::value
0063 && std::ratio_equal<E1,E2>::value
0064 && std::ratio_equal<Q1,Q2>::value;
0065 };
0066
0067 template <typename T>
0068 struct is_qty {
0069 static constexpr bool value = qty_equal<T,T>::value;
0070 };
0071
0072 template <typename ResultT, typename T, typename U = T>
0073 using enable_if_same_qty = typename std::enable_if<qty_equal<T,U>::value, ResultT>::type;
0074
0075 template<long int L, long int E, long int Q, long int DL, long int DE, long int DQ>
0076 class Qty<std::ratio<L,DL>, std::ratio<E,DE>, std::ratio<Q,DQ>>
0077 {
0078 private:
0079
0080 constexpr Qty(double val) : rawValue_(val) {}
0081
0082 public:
0083
0084
0085 static std::string className() {
0086 std::ostringstream os;
0087 os << "Qty<"
0088 << L << ','
0089 << E << ','
0090 << Q << ','
0091 << DL << ','
0092 << DE << ','
0093 << DQ << '>';
0094
0095 return os.str();
0096 }
0097
0098
0099 template <long int Num, long int Den>
0100 using Power = Qty<typename std::ratio<Num*L,Den*DL>::type,
0101 typename std::ratio<Num*E,Den*DE>::type,
0102 typename std::ratio<Num*Q,Den*DQ>::type>;
0103
0104 using Type = Power<1,1>;
0105
0106 using Squared = Power<2,1>;
0107
0108 using Inverse = Power<-1,1>;
0109
0110 using Sqrt = Power<1,2>;
0111
0112
0113 static constexpr Type baseunit()
0114 {
0115 return Type(1.0);
0116 }
0117
0118
0119 constexpr Qty() : rawValue_(0.0) {}
0120
0121
0122 constexpr Qty(ZeroUnit) : rawValue_(0.0) {}
0123
0124
0125 template <typename U>
0126 constexpr Qty(const U & q, double factor = 1.0,
0127 enable_if_same_qty<void,Type,U> * = nullptr)
0128 : rawValue_(q.rawValue() * factor) {}
0129
0130
0131 constexpr double rawValue() const { return rawValue_; }
0132
0133
0134 Type & operator*=(double x) { rawValue_ *= x; return *this; }
0135
0136
0137 Type & operator/=(double x) { rawValue_ /= x; return *this; }
0138
0139
0140 Type & operator+=(const Type & x)
0141 {
0142 rawValue_ += x.rawValue();
0143 return *this;
0144 }
0145
0146
0147 Type & operator-=(const Type & x)
0148 {
0149 rawValue_ -= x.rawValue();
0150 return *this;
0151 }
0152
0153 private:
0154
0155 double rawValue_;
0156 };
0157
0158
0159 template<>
0160 class Qty<std::ratio<0>,std::ratio<0>,std::ratio<0>>
0161 {
0162 public:
0163
0164 using Type = Qty<std::ratio<0>,std::ratio<0>,std::ratio<0>>;
0165
0166 template <long int Num, long int Den>
0167 using Power = Type;
0168
0169 using Squared = Type;
0170
0171 using Inverse = Type;
0172
0173 using Sqrt = Type;
0174
0175
0176
0177 static constexpr Type baseunit() {
0178 return 1.0;
0179 }
0180
0181
0182 constexpr Qty(ZeroUnit) : rawValue_(0.0) {}
0183
0184
0185 constexpr Qty(double x = 0.0, double factor=1.0)
0186 : rawValue_(x * factor) {}
0187
0188
0189 template <typename U>
0190 constexpr Qty(const U & q, double factor=1.0,
0191 enable_if_same_qty<void,Type,U> * = nullptr)
0192 : rawValue_(q.rawValue() * factor) {}
0193
0194
0195 constexpr double rawValue() const { return rawValue_; }
0196
0197
0198 constexpr operator double() const { return rawValue_; }
0199
0200
0201 Type & operator*=(double x) { rawValue_ *= x; return *this; }
0202
0203
0204 Type & operator/=(double x) { rawValue_ /= x; return *this; }
0205
0206
0207 Type & operator+=(const Type & x) {
0208 rawValue_ += x.rawValue();
0209 return *this;
0210 }
0211
0212
0213 Type & operator-=(const Type & x) {
0214 rawValue_ -= x.rawValue();
0215 return *this;
0216 }
0217
0218
0219 Type & operator+=(double x) {
0220 rawValue_ += x;
0221 return *this;
0222 }
0223
0224
0225 Type & operator-=(double x) {
0226 rawValue_ -= x;
0227 return *this;
0228 }
0229
0230 private:
0231
0232 double rawValue_;
0233 };
0234
0235 using QtyDouble = Qty<std::ratio<0>,std::ratio<0>,std::ratio<0>>;
0236
0237
0238
0239
0240
0241
0242
0243
0244 template <typename T, typename U>
0245 struct BinaryOpTraits;
0246
0247
0248
0249 template<typename L1, typename L2,
0250 typename E1, typename E2,
0251 typename Q1, typename Q2>
0252 struct BinaryOpTraits<Qty<L1,E1,Q1>, Qty<L2,E2,Q2>> {
0253
0254
0255 typedef Qty<std::ratio_add<L1,L2>,
0256 std::ratio_add<E1,E2>,
0257 std::ratio_add<Q1,Q2>> MulT;
0258
0259
0260 typedef Qty<std::ratio_subtract<L1,L2>,
0261 std::ratio_subtract<E1,E2>,
0262 std::ratio_subtract<Q1,Q2>> DivT;
0263 };
0264
0265
0266
0267
0268 template<typename L, typename E, typename Q>
0269 struct BinaryOpTraits<double, Qty<L,E,Q>> {
0270
0271 typedef Qty<L,E,Q> MulT;
0272
0273 typedef typename BinaryOpTraits<QtyDouble, Qty<L,E,Q>>::DivT DivT;
0274 };
0275
0276
0277
0278
0279 template<typename L, typename E, typename Q>
0280 struct BinaryOpTraits<Qty<L,E,Q>, double> {
0281
0282 typedef Qty<L,E,Q> MulT;
0283
0284 typedef Qty<L,E,Q> DivT;
0285 };
0286
0287
0288
0289
0290
0291 template <typename L, typename E, typename Q>
0292 struct TypeTraits<Qty<L,E,Q>>
0293 {
0294
0295 enum { hasDimension = true };
0296
0297 typedef DimensionT DimType;
0298
0299 static constexpr Qty<L,E,Q> baseunit()
0300 { return Qty<L,E,Q>::baseunit(); }
0301 };
0302
0303
0304 template <>
0305 struct TypeTraits<QtyDouble>
0306 {
0307
0308 enum { hasDimension = false };
0309
0310 typedef StandardT DimType;
0311
0312 static constexpr QtyDouble baseunit() { return 1.0; }
0313 };
0314
0315
0316
0317
0318
0319 }
0320
0321 #endif