thepeg is hosted by Hepforge, IPPP Durham
ThePEG  2.2.1
PhysicalQty.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // PhysicalQty.h is a part of ThePEG - Toolkit for HEP Event Generation
4 // Copyright (C) 2006-2019 David Grellscheid, Leif Lonnblad
5 //
6 // ThePEG is licenced under version 3 of the GPL, see COPYING for details.
7 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
8 //
9 #ifndef Physical_Qty_H
10 #define Physical_Qty_H
11 #include "TemplateTools.h"
12 #include <sstream>
13 #include <ratio>
14 #include <type_traits>
15 
26 namespace ThePEG {
27 
29 struct ZeroUnit {
31  constexpr operator double() const { return 0.0; }
32 };
33 
35 constexpr ZeroUnit ZERO = ZeroUnit();
36 
50 // only specialization is with std::ratio below
51 template <typename L, typename E, typename T>
52 class Qty;
53 
54 template <typename T, typename U>
55 struct qty_equal {
56  static constexpr bool value = false;
57 };
58 
59 template<typename L1, typename L2, typename E1, typename E2, typename Q1, typename Q2>
60 struct qty_equal<Qty<L1,E1,Q1>, Qty<L2,E2,Q2>> {
61  static constexpr bool value
62  = std::ratio_equal<L1,L2>::value
63  && std::ratio_equal<E1,E2>::value
64  && std::ratio_equal<Q1,Q2>::value;
65 };
66 
67 template <typename T>
68 struct is_qty {
69  static constexpr bool value = qty_equal<T,T>::value;
70 };
71 
72 template <typename ResultT, typename T, typename U = T>
73 using enable_if_same_qty = typename std::enable_if<qty_equal<T,U>::value, ResultT>::type;
74 
75 template<long int L, long int E, long int Q, long int DL, long int DE, long int DQ>
76 class Qty<std::ratio<L,DL>, std::ratio<E,DE>, std::ratio<Q,DQ>>
77 {
78 private:
80  constexpr Qty(double val) : rawValue_(val) {}
81 
82 public:
83 
85  static std::string className() {
86  std::ostringstream os;
87  os << "Qty<"
88  << L << ','
89  << E << ','
90  << Q << ','
91  << DL << ','
92  << DE << ','
93  << DQ << '>';
94 
95  return os.str();
96  }
97 
99  template <long int Num, long int Den>
100  using Power = Qty<typename std::ratio<Num*L,Den*DL>::type,
101  typename std::ratio<Num*E,Den*DE>::type,
102  typename std::ratio<Num*Q,Den*DQ>::type>;
104  using Type = Power<1,1>;
106  using Squared = Power<2,1>;
108  using Inverse = Power<-1,1>;
110  using Sqrt = Power<1,2>;
111 
113  static constexpr Type baseunit()
114  {
115  return Type(1.0);
116  }
117 
119  constexpr Qty() : rawValue_(0.0) {}
120 
122  constexpr Qty(ZeroUnit) : rawValue_(0.0) {}
123 
125  template <typename U>
126  constexpr Qty(const U & q, double factor = 1.0,
127  enable_if_same_qty<void,Type,U> * = nullptr)
128  : rawValue_(q.rawValue() * factor) {}
129 
131  constexpr double rawValue() const { return rawValue_; }
132 
134  Type & operator*=(double x) { rawValue_ *= x; return *this; }
135 
137  Type & operator/=(double x) { rawValue_ /= x; return *this; }
138 
140  Type & operator+=(const Type & x)
141  {
142  rawValue_ += x.rawValue();
143  return *this;
144  }
145 
147  Type & operator-=(const Type & x)
148  {
149  rawValue_ -= x.rawValue();
150  return *this;
151  }
152 
153 private:
155  double rawValue_;
156 };
157 
159 template<>
160 class Qty<std::ratio<0>,std::ratio<0>,std::ratio<0>>
161 {
162 public:
164  using Type = Qty<std::ratio<0>,std::ratio<0>,std::ratio<0>>;
166  template <long int Num, long int Den>
167  using Power = Type;
169  using Squared = Type;
171  using Inverse = Type;
173  using Sqrt = Type;
174 
175 
177  static constexpr Type baseunit() {
178  return 1.0;
179  }
180 
182  constexpr Qty(ZeroUnit) : rawValue_(0.0) {}
183 
185  constexpr Qty(double x = 0.0, double factor=1.0)
186  : rawValue_(x * factor) {}
187 
189  template <typename U>
190  constexpr Qty(const U & q, double factor=1.0,
191  enable_if_same_qty<void,Type,U> * = nullptr)
192  : rawValue_(q.rawValue() * factor) {}
193 
195  constexpr double rawValue() const { return rawValue_; }
196 
198  constexpr operator double() const { return rawValue_; }
199 
201  Type & operator*=(double x) { rawValue_ *= x; return *this; }
202 
204  Type & operator/=(double x) { rawValue_ /= x; return *this; }
205 
207  Type & operator+=(const Type & x) {
208  rawValue_ += x.rawValue();
209  return *this;
210  }
211 
213  Type & operator-=(const Type & x) {
214  rawValue_ -= x.rawValue();
215  return *this;
216  }
217 
219  Type & operator+=(double x) {
220  rawValue_ += x;
221  return *this;
222  }
223 
225  Type & operator-=(double x) {
226  rawValue_ -= x;
227  return *this;
228  }
229 
230 private:
232  double rawValue_;
233 };
234 
235 using QtyDouble = Qty<std::ratio<0>,std::ratio<0>,std::ratio<0>>;
236 
238 
239 
244 template <typename T, typename U>
245 struct BinaryOpTraits;
246 
249 template<typename L1, typename L2,
250  typename E1, typename E2,
251  typename Q1, typename Q2>
252 struct BinaryOpTraits<Qty<L1,E1,Q1>, Qty<L2,E2,Q2>> {
255  typedef Qty<std::ratio_add<L1,L2>,
256  std::ratio_add<E1,E2>,
257  std::ratio_add<Q1,Q2>> MulT;
260  typedef Qty<std::ratio_subtract<L1,L2>,
261  std::ratio_subtract<E1,E2>,
262  std::ratio_subtract<Q1,Q2>> DivT;
263 };
264 
268 template<typename L, typename E, typename Q>
269 struct BinaryOpTraits<double, Qty<L,E,Q>> {
271  typedef Qty<L,E,Q> MulT;
273  typedef typename BinaryOpTraits<QtyDouble, Qty<L,E,Q>>::DivT DivT;
274 };
275 
279 template<typename L, typename E, typename Q>
280 struct BinaryOpTraits<Qty<L,E,Q>, double> {
282  typedef Qty<L,E,Q> MulT;
284  typedef Qty<L,E,Q> DivT;
285 };
287 
289 
290 /** Type traits for alternative code generation*/
291 template <typename L, typename E, typename Q>
292 struct TypeTraits<Qty<L,E,Q>>
293 {
295  enum { hasDimension = true };
297  typedef DimensionT DimType;
299  static constexpr Qty<L,E,Q> baseunit()
300  { return Qty<L,E,Q>::baseunit(); }
301 };
302 
304 template <>
305 struct TypeTraits<QtyDouble>
306 {
308  enum { hasDimension = false };
310  typedef StandardT DimType;
312  static constexpr QtyDouble baseunit() { return 1.0; }
313 };
314 
316 
319 }
320 
321 #endif
Helper class to construct zero unitful quantities.
Definition: PhysicalQty.h:29
STL namespace.
This is the main namespace within which all identifiers in ThePEG are declared.
Definition: FactoryBase.h:28
constexpr Qty(double val)
Constructor from raw values. Breaks consistency.
Definition: PhysicalQty.h:80
static std::string className()
The name of the class for persistent IO.
Definition: PhysicalQty.h:85
This template class allows the compiler to check calculations with physical quantities for dimensiona...
Definition: PhysicalQty.h:52
constexpr ZeroUnit ZERO
ZERO can be used as zero for any unitful quantity.
Definition: PhysicalQty.h:35
Useful template machinery.