Rivet API documentation

Rivet 4.1.3
Cmp.hh
1// -*- C++ -*-
2#ifndef RIVET_Cmp_HH
3#define RIVET_Cmp_HH
4
5#include "Rivet/Projection.hh"
6#include "Rivet/Config/RivetCommon.hh"
7#include "Cmp.fhh"
8#include <typeinfo>
9
10
11namespace Rivet {
12
13
26 template <typename T>
27 class Cmp final {
28 public:
29
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))
74 _value = CmpState::NEQ;
75 else if (l(*_objects.second, *_objects.first))
76 _value = CmpState::NEQ;
77 else
78 _value = CmpState::EQ;
79 }
80 }
81
83 mutable CmpState _value;
84
86 const pair<const T*, const T*> _objects;
87 };
88
89
104 template <>
105 class Cmp<Projection> final {
106 public:
107
111 Cmp(const Projection& p1, const Projection& p2)
112 : _value(CmpState::UNDEF), _objects(&p1, &p2) { }
113
115 template <typename U>
116 Cmp(const Cmp<U>& x)
117 : _value(x), _objects(nullptr, nullptr) { }
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))
151 _value = CmpState::NEQ;
152 else if (id2.before(id1))
153 _value = CmpState::NEQ;
154 else {
155 CmpState cmps = _objects.first->compare(*_objects.second);
156 if (cmps == CmpState::EQ)
157 _value = CmpState::EQ;
158 else
159 _value = CmpState::NEQ;
160 }
161 }
162 }
163
164 private:
165
167 mutable CmpState _value;
168
170 const pair<const Projection*, const Projection*> _objects;
171 };
172
173
187 template <>
188 class Cmp<double> final {
189 public:
190
194 Cmp(const double p1, const double p2)
195 : _value(CmpState::UNDEF), _numA(p1), _numB(p2) { }
196
198 template <typename U>
199 Cmp(const Cmp<U>& x)
200 : _value(x), _numA(0.0), _numB(0.0) { }
201
203 template <typename U>
204 const Cmp<double>& operator=(const Cmp<U>& x) {
205 _value = x;
206 return *this;
207 }
209
210 public:
211
213 operator CmpState() const {
214 _compare();
215 return _value;
216 }
217
219 template <typename U>
220 const Cmp<double>& operator||(const Cmp<U>& c) const {
221 _compare();
222 if (_value == CmpState::EQ) _value = c;
223 return *this;
224 }
225
226 private:
227
229 void _compare() const {
230 if (_value == CmpState::UNDEF) {
231 if (fuzzyEquals(_numA, _numB))
232 _value = CmpState::EQ;
233 else
234 _value = CmpState::NEQ;
235 }
236 }
237
238 private:
239
241 mutable CmpState _value;
242
244 const double _numA, _numB;
245 };
246
247
249
250
252 template <typename T>
253 inline Cmp<T> cmp(const T& t1, const T& t2) {
254 return Cmp<T>(t1, t2);
255 }
256
257
259 using PCmp = Cmp<Projection>;
260
261
263 inline Cmp<Projection> pcmp(const Projection& p1, const Projection& p2) {
264 return Cmp<Projection>(p1, p2);
265 }
266
269 inline Cmp<Projection> pcmp(const Projection& parent1, const Projection& parent2, const string& pname) {
270 return Cmp<Projection>(parent1.getProjection(pname), parent2.getProjection(pname));
271 }
272
276 inline Cmp<Projection> pcmp(const Projection* parent1, const Projection& parent2, const string& pname) {
277 assert(parent1);
278 return Cmp<Projection>(parent1->getProjection(pname), parent2.getProjection(pname));
279 }
280
284 inline Cmp<Projection> pcmp(const Projection& parent1, const Projection* parent2, const string& pname) {
285 assert(parent2);
286 return Cmp<Projection>(parent1.getProjection(pname), parent2->getProjection(pname));
287 }
288
291 inline Cmp<Projection> pcmp(const Projection* parent1, const Projection* parent2, const string& pname) {
292 assert(parent1);
293 assert(parent2);
294 return Cmp<Projection>(parent1->getProjection(pname), parent2->getProjection(pname));
295 }
296
297
298}
299
300
301#endif
const PROJ & getProjection(const std::string &name) const
Definition ProjectionApplier.hh:72
Base class for all Rivet projections.
Definition Projection.hh:29
Definition LHCbCommon.hh:9
Cmp< Projection > PCmp
Typedef for Cmp<Projection>.
Definition Cmp.hh:259
Cmp< Projection > pcmp(const Projection &p1, const Projection &p2)
Global helper function for easy creation of Cmp<Projection> objects.
Definition Cmp.hh:263
Cmp< T > cmp(const T &t1, const T &t2)
Global helper function for easy creation of Cmp objects.
Definition Cmp.hh:253
std::enable_if_t< std::is_arithmetic_v< N1 > &&std::is_arithmetic_v< N2 > &&(std::is_floating_point_v< N1 >||std::is_floating_point_v< N2 >), bool > fuzzyEquals(N1 a, N2 b, double tolerance=1e-5)
Compare two numbers for equality with a degree of fuzziness.
Definition MathUtils.hh:66