Rivet  3.1.3
Cmp.hh
1 // -*- C++ -*-
2 #ifndef RIVET_Cmp_HH
3 #define RIVET_Cmp_HH
4 
5 #include "Rivet/Config/RivetCommon.hh"
6 #include "Rivet/Projection.hh"
7 #include "Cmp.fhh"
8 #include <typeinfo>
9 
10 
11 namespace Rivet {
12 
13 
26  template <typename T>
27  class Cmp final {
28  public:
29 
31 
32 
34  Cmp(const T& t1, const T& t2)
35  : _value(CmpState::UNDEF), _objects(&t1, &t2) { }
36 
38  template <typename U>
39  Cmp(const Cmp<U>& x)
40  : _value(x._value), _objects(nullptr, nullptr) { }
41 
43  template <typename U>
44  const Cmp<T>& operator=(const Cmp<U>& x) {
45  _value = x;
46  return *this;
47  }
48 
50 
51  public:
52 
54  operator CmpState() const {
55  _compare();
56  return _value;
57  }
58 
60  template <typename U>
61  const Cmp<T>& operator||(const Cmp<U>& c) const {
62  _compare();
63  if (_value == CmpState::EQ) _value = c;
64  return *this;
65  }
66 
67  private:
68 
70  void _compare() const {
71  if (_value == CmpState::UNDEF) {
72  std::less<T> l;
73  if ( l(*_objects.first, *_objects.second) ) _value = CmpState::NEQ;
74  else if ( l(*_objects.second, *_objects.first) ) _value = CmpState::NEQ;
75  else _value = CmpState::EQ;
76  }
77  }
78 
80  mutable CmpState _value;
81 
83  const pair<const T*, const T*> _objects;
84 
85  };
86 
87 
102  template <>
103  class Cmp<Projection> final {
104  public:
105 
107 
108  Cmp(const Projection& p1, const Projection& p2)
110  : _value(CmpState::UNDEF), _objects(&p1, &p2)
111  { }
112 
114  template <typename U>
115  Cmp(const Cmp<U>& x)
116  : _value(x), _objects(nullptr, nullptr)
117  { }
118 
120  template <typename U>
121  const Cmp<Projection>& operator=(const Cmp<U>& x) {
122  _value = x;
123  return *this;
124  }
126 
127  public:
128 
130  operator CmpState() const {
131  _compare();
132  return _value;
133  }
134 
136  template <typename U>
137  const Cmp<Projection>& operator||(const Cmp<U>& c) const {
138  _compare();
139  if (_value == CmpState::EQ) _value = c;
140  return *this;
141  }
142 
143  private:
144 
146  void _compare() const {
147  if (_value == CmpState::UNDEF) {
148  const std::type_info& id1 = typeid(*_objects.first);
149  const std::type_info& id2 = typeid(*_objects.second);
150  if (id1.before(id2)) _value = CmpState::NEQ;
151  else if (id2.before(id1)) _value = CmpState::NEQ;
152  else {
153  CmpState cmps = _objects.first->compare(*_objects.second);
154  if (cmps == CmpState::EQ) _value = CmpState::EQ;
155  else _value = CmpState::NEQ;
156  }
157  }
158  }
159 
160  private:
161 
163  mutable CmpState _value;
164 
166  const pair<const Projection*, const Projection*> _objects;
167 
168  };
169 
170 
171 
172 
186  template <>
187  class Cmp<double> final {
188  public:
189 
191 
192  Cmp(const double p1, const double p2)
194  : _value(CmpState::UNDEF), _numA(p1), _numB(p2)
195  { }
196 
198  template <typename U>
199  Cmp(const Cmp<U>& x)
200  : _value(x), _numA(0.0), _numB(0.0)
201  { }
202 
204  template <typename U>
205  const Cmp<double>& operator=(const Cmp<U>& x) {
206  _value = x;
207  return *this;
208  }
210 
211  public:
212 
214  operator CmpState() const {
215  _compare();
216  return _value;
217  }
218 
220  template <typename U>
221  const Cmp<double>& operator||(const Cmp<U>& c) const {
222  _compare();
223  if (_value == CmpState::EQ) _value = c;
224  return *this;
225  }
226 
227  private:
228 
230  void _compare() const {
231  if (_value == CmpState::UNDEF) {
232  if (fuzzyEquals(_numA,_numB)) _value = CmpState::EQ;
233  else _value = CmpState::NEQ;
234  }
235  }
236 
237  private:
238 
240  mutable CmpState _value;
241 
243  const double _numA, _numB;
244 
245  };
246 
247 
248 
250 
251 
252 
254  template <typename T>
255  inline Cmp<T> cmp(const T& t1, const T& t2) {
256  return Cmp<T>(t1, t2);
257  }
258 
259 
261  using PCmp = Cmp<Projection>;
262 
263 
265  inline Cmp<Projection> pcmp(const Projection& p1, const Projection& p2) {
266  return Cmp<Projection>(p1, p2);
267  }
268 
271  inline Cmp<Projection> pcmp(const Projection& parent1, const Projection& parent2, const string& pname) {
272  return Cmp<Projection>(parent1.getProjection(pname), parent2.getProjection(pname));
273  }
274 
278  inline Cmp<Projection> pcmp(const Projection* parent1, const Projection& parent2, const string& pname) {
279  assert(parent1);
280  return Cmp<Projection>(parent1->getProjection(pname), parent2.getProjection(pname));
281  }
282 
286  inline Cmp<Projection> pcmp(const Projection& parent1, const Projection* parent2, const string& pname) {
287  assert(parent2);
288  return Cmp<Projection>(parent1.getProjection(pname), parent2->getProjection(pname));
289  }
290 
293  inline Cmp<Projection> pcmp(const Projection* parent1, const Projection* parent2, const string& pname) {
294  assert(parent1);
295  assert(parent2);
296  return Cmp<Projection>(parent1->getProjection(pname), parent2->getProjection(pname));
297  }
298 
299 
300 }
301 
302 
303 #endif
Definition: MC_Cent_pPb.hh:10
Cut operator||(const Cut &aptr, const Cut &bptr)
Cmp< Projection > pcmp(const Projection &p1, const Projection &p2)
Global helper function for easy creation of Cmp<Projection> objects.
Definition: Cmp.hh:265
std::enable_if< std::is_arithmetic< N1 >::value &&std::is_arithmetic< N2 >::value &&(std::is_floating_point< N1 >::value||std::is_floating_point< N2 >::value), bool >::type fuzzyEquals(N1 a, N2 b, double tolerance=1e-5)
Compare two numbers for equality with a degree of fuzziness.
Definition: MathUtils.hh:57
const PROJ & getProjection(const std::string &name) const
Definition: ProjectionApplier.hh:56
Cmp< Projection > PCmp
Typedef for Cmp<Projection>
Definition: Cmp.hh:261
Base class for all Rivet projections.
Definition: Projection.hh:29
Cmp< T > cmp(const T &t1, const T &t2)
Global helper function for easy creation of Cmp objects.
Definition: Cmp.hh:255