File indexing completed on 2025-04-19 09:06:50
0001
0002 #ifndef RIVET_Cmp_HH
0003 #define RIVET_Cmp_HH
0004
0005 #include "Rivet/Config/RivetCommon.hh"
0006 #include "Rivet/Projection.hh"
0007 #include "Cmp.fhh"
0008 #include <typeinfo>
0009
0010
0011 namespace Rivet {
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 template <typename T>
0027 class Cmp final {
0028 public:
0029
0030
0031
0032
0033
0034 Cmp(const T& t1, const T& t2)
0035 : _value(CmpState::UNDEF), _objects(&t1, &t2) { }
0036
0037
0038 template <typename U>
0039 Cmp(const Cmp<U>& x)
0040 : _value(x._value), _objects(nullptr, nullptr) { }
0041
0042
0043 template <typename U>
0044 const Cmp<T>& operator=(const Cmp<U>& x) {
0045 _value = x;
0046 return *this;
0047 }
0048
0049
0050
0051 public:
0052
0053
0054 operator CmpState() const {
0055 _compare();
0056 return _value;
0057 }
0058
0059
0060 template <typename U>
0061 const Cmp<T>& operator||(const Cmp<U>& c) const {
0062 _compare();
0063 if (_value == CmpState::EQ) _value = c;
0064 return *this;
0065 }
0066
0067 private:
0068
0069
0070 void _compare() const {
0071 if (_value == CmpState::UNDEF) {
0072 std::less<T> l;
0073 if ( l(*_objects.first, *_objects.second) ) _value = CmpState::NEQ;
0074 else if ( l(*_objects.second, *_objects.first) ) _value = CmpState::NEQ;
0075 else _value = CmpState::EQ;
0076 }
0077 }
0078
0079
0080 mutable CmpState _value;
0081
0082
0083 const pair<const T*, const T*> _objects;
0084
0085 };
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102 template <>
0103 class Cmp<Projection> final {
0104 public:
0105
0106
0107
0108
0109 Cmp(const Projection& p1, const Projection& p2)
0110 : _value(CmpState::UNDEF), _objects(&p1, &p2)
0111 { }
0112
0113
0114 template <typename U>
0115 Cmp(const Cmp<U>& x)
0116 : _value(x), _objects(nullptr, nullptr)
0117 { }
0118
0119
0120 template <typename U>
0121 const Cmp<Projection>& operator=(const Cmp<U>& x) {
0122 _value = x;
0123 return *this;
0124 }
0125
0126
0127 public:
0128
0129
0130 operator CmpState() const {
0131 _compare();
0132 return _value;
0133 }
0134
0135
0136 template <typename U>
0137 const Cmp<Projection>& operator||(const Cmp<U>& c) const {
0138 _compare();
0139 if (_value == CmpState::EQ) _value = c;
0140 return *this;
0141 }
0142
0143 private:
0144
0145
0146 void _compare() const {
0147 if (_value == CmpState::UNDEF) {
0148 const std::type_info& id1 = typeid(*_objects.first);
0149 const std::type_info& id2 = typeid(*_objects.second);
0150 if (id1.before(id2)) _value = CmpState::NEQ;
0151 else if (id2.before(id1)) _value = CmpState::NEQ;
0152 else {
0153 CmpState cmps = _objects.first->compare(*_objects.second);
0154 if (cmps == CmpState::EQ) _value = CmpState::EQ;
0155 else _value = CmpState::NEQ;
0156 }
0157 }
0158 }
0159
0160 private:
0161
0162
0163 mutable CmpState _value;
0164
0165
0166 const pair<const Projection*, const Projection*> _objects;
0167
0168 };
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186 template <>
0187 class Cmp<double> final {
0188 public:
0189
0190
0191
0192
0193 Cmp(const double p1, const double p2)
0194 : _value(CmpState::UNDEF), _numA(p1), _numB(p2)
0195 { }
0196
0197
0198 template <typename U>
0199 Cmp(const Cmp<U>& x)
0200 : _value(x), _numA(0.0), _numB(0.0)
0201 { }
0202
0203
0204 template <typename U>
0205 const Cmp<double>& operator=(const Cmp<U>& x) {
0206 _value = x;
0207 return *this;
0208 }
0209
0210
0211 public:
0212
0213
0214 operator CmpState() const {
0215 _compare();
0216 return _value;
0217 }
0218
0219
0220 template <typename U>
0221 const Cmp<double>& operator||(const Cmp<U>& c) const {
0222 _compare();
0223 if (_value == CmpState::EQ) _value = c;
0224 return *this;
0225 }
0226
0227 private:
0228
0229
0230 void _compare() const {
0231 if (_value == CmpState::UNDEF) {
0232 if (fuzzyEquals(_numA,_numB)) _value = CmpState::EQ;
0233 else _value = CmpState::NEQ;
0234 }
0235 }
0236
0237 private:
0238
0239
0240 mutable CmpState _value;
0241
0242
0243 const double _numA, _numB;
0244
0245 };
0246
0247
0248
0249
0250
0251
0252
0253
0254 template <typename T>
0255 inline Cmp<T> cmp(const T& t1, const T& t2) {
0256 return Cmp<T>(t1, t2);
0257 }
0258
0259
0260
0261 using PCmp = Cmp<Projection>;
0262
0263
0264
0265 inline Cmp<Projection> pcmp(const Projection& p1, const Projection& p2) {
0266 return Cmp<Projection>(p1, p2);
0267 }
0268
0269
0270
0271 inline Cmp<Projection> pcmp(const Projection& parent1, const Projection& parent2, const string& pname) {
0272 return Cmp<Projection>(parent1.getProjection(pname), parent2.getProjection(pname));
0273 }
0274
0275
0276
0277
0278 inline Cmp<Projection> pcmp(const Projection* parent1, const Projection& parent2, const string& pname) {
0279 assert(parent1);
0280 return Cmp<Projection>(parent1->getProjection(pname), parent2.getProjection(pname));
0281 }
0282
0283
0284
0285
0286 inline Cmp<Projection> pcmp(const Projection& parent1, const Projection* parent2, const string& pname) {
0287 assert(parent2);
0288 return Cmp<Projection>(parent1.getProjection(pname), parent2->getProjection(pname));
0289 }
0290
0291
0292
0293 inline Cmp<Projection> pcmp(const Projection* parent1, const Projection* parent2, const string& pname) {
0294 assert(parent1);
0295 assert(parent2);
0296 return Cmp<Projection>(parent1->getProjection(pname), parent2->getProjection(pname));
0297 }
0298
0299
0300 }
0301
0302
0303 #endif