rivet is hosted by Hepforge, IPPP Durham
Rivet 4.0.0
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
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) ) _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
109 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
193 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
const PROJ & getProjection(const std::string &name) const
Definition ProjectionApplier.hh:62
Base class for all Rivet projections.
Definition Projection.hh:29
Definition MC_CENT_PPB_Projections.hh:10
Cmp< Projection > PCmp
Typedef for Cmp<Projection>
Definition Cmp.hh:261
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
Cmp< T > cmp(const T &t1, const T &t2)
Global helper function for easy creation of Cmp objects.
Definition Cmp.hh:255
Cut operator||(const Cut &aptr, const Cut &bptr)