Cmp.hh
Go to the documentation of this file.00001
00002 #ifndef RIVET_Cmp_HH
00003 #define RIVET_Cmp_HH
00004
00005 #include "Rivet/Rivet.hh"
00006 #include "Rivet/Projection.hh"
00007 #include "Cmp.fhh"
00008 #include <typeinfo>
00009
00010
00011 namespace Rivet {
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 template <typename T>
00027 class Cmp {
00028 public:
00029
00030
00031
00032
00033
00034 Cmp(const T& t1, const T& t2)
00035 : _value(UNDEFINED), _objects(&t1, &t2) { }
00036
00037
00038 template <typename U>
00039 Cmp(const Cmp<U>& x)
00040 : _value(x), _objects(0, 0) { }
00041
00042
00043 ~Cmp() { };
00044
00045
00046 template <typename U>
00047 const Cmp<T>& operator=(const Cmp<U>& x) {
00048 _value = x;
00049 return *this;
00050 }
00051
00052
00053
00054 public:
00055
00056
00057 operator CmpState() const {
00058 _compare();
00059 return _value;
00060 }
00061
00062
00063 operator int() const {
00064 _compare();
00065 return _value;
00066 }
00067
00068
00069 template <typename U>
00070 const Cmp<T>& operator||(const Cmp<U>& c) const {
00071 _compare();
00072 if (_value == EQUIVALENT) _value = c;
00073 return *this;
00074 }
00075
00076 private:
00077
00078
00079 void _compare() const {
00080 if (_value == UNDEFINED) {
00081 less<T> l;
00082 if ( l(*_objects.first, *_objects.second) ) _value = ORDERED;
00083 else if ( l(*_objects.second, *_objects.first) ) _value = UNORDERED;
00084 else _value = EQUIVALENT;
00085 }
00086 }
00087
00088
00089 mutable CmpState _value;
00090
00091
00092 pair<const T*, const T*> _objects;
00093
00094 };
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 template <>
00112 class Cmp<Projection> {
00113 public:
00114
00115
00116
00117
00118 Cmp(const Projection& p1, const Projection& p2)
00119 : _value(UNDEFINED), _objects(&p1, &p2)
00120 { }
00121
00122
00123 template <typename U>
00124 Cmp(const Cmp<U>& x)
00125 : _value(x), _objects(0, 0)
00126 { }
00127
00128
00129 ~Cmp() { };
00130
00131
00132 template <typename U>
00133 const Cmp<Projection>& operator=(const Cmp<U>& x) {
00134 _value = x;
00135 return *this;
00136 }
00137
00138
00139 public:
00140
00141
00142 operator CmpState() const {
00143 _compare();
00144 return _value;
00145 }
00146
00147
00148
00149 operator int() const {
00150 _compare();
00151 return _value;
00152 }
00153
00154
00155 template <typename U>
00156 const Cmp<Projection>& operator||(const Cmp<U>& c) const {
00157 _compare();
00158 if (_value == EQUIVALENT) _value = c;
00159 return *this;
00160 }
00161
00162 private:
00163
00164
00165 void _compare() const {
00166 if (_value == UNDEFINED) {
00167 const std::type_info& id1 = typeid(*_objects.first);
00168 const std::type_info& id2 = typeid(*_objects.second);
00169 if (id1.before(id2)) _value = ORDERED;
00170 else if (id2.before(id1)) _value = UNORDERED;
00171 else {
00172 int c = _objects.first->compare(*_objects.second);
00173 if (c < 0) _value = ORDERED;
00174 else if (c > 0) _value = UNORDERED;
00175 else _value = EQUIVALENT;
00176 }
00177 }
00178 }
00179
00180 private:
00181
00182
00183 mutable CmpState _value;
00184
00185
00186 pair<const Projection*, const Projection*> _objects;
00187
00188 };
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206 template <>
00207 class Cmp<double> {
00208 public:
00209
00210
00211
00212
00213 Cmp(const double p1, const double p2)
00214 : _value(UNDEFINED), _numA(p1), _numB(p2)
00215 { }
00216
00217
00218 template <typename U>
00219 Cmp(const Cmp<U>& x)
00220 : _value(x), _numA(0.0), _numB(0.0)
00221 { }
00222
00223
00224 ~Cmp() { }
00225
00226
00227 template <typename U>
00228 const Cmp<double>& operator=(const Cmp<U>& x) {
00229 _value = x;
00230 return *this;
00231 }
00232
00233
00234 public:
00235
00236
00237 operator CmpState() const {
00238 _compare();
00239 return _value;
00240 }
00241
00242
00243 operator int() const {
00244 _compare();
00245 return _value;
00246 }
00247
00248
00249 template <typename U>
00250 const Cmp<double>& operator||(const Cmp<U>& c) const {
00251 _compare();
00252 if (_value == EQUIVALENT) _value = c;
00253 return *this;
00254 }
00255
00256 private:
00257
00258
00259 void _compare() const {
00260 if (_value == UNDEFINED) {
00261 if (fuzzyEquals(_numA,_numB)) _value = EQUIVALENT;
00262 else if (_numA < _numB) _value = ORDERED;
00263 else _value = UNORDERED;
00264 }
00265 }
00266
00267 private:
00268
00269
00270 mutable CmpState _value;
00271
00272
00273 double _numA, _numB;
00274
00275 };
00276
00277
00278
00279
00280
00281
00282
00283
00284 template <typename T>
00285 inline Cmp<T> cmp(const T& t1, const T& t2) {
00286 return Cmp<T>(t1, t2);
00287 }
00288
00289
00290
00291 typedef Cmp<Projection> PCmp;
00292
00293
00294
00295 inline Cmp<Projection> pcmp(const Projection& p1, const Projection& p2) {
00296 return Cmp<Projection>(p1, p2);
00297 }
00298
00299
00300
00301 inline Cmp<Projection> pcmp(const Projection& parent1, const Projection& parent2, const string& pname) {
00302 return Cmp<Projection>(parent1.getProjection(pname), parent2.getProjection(pname));
00303 }
00304
00305
00306
00307
00308 inline Cmp<Projection> pcmp(const Projection* parent1, const Projection& parent2, const string& pname) {
00309 assert(parent1);
00310 return Cmp<Projection>(parent1->getProjection(pname), parent2.getProjection(pname));
00311 }
00312
00313
00314
00315
00316 inline Cmp<Projection> pcmp(const Projection& parent1, const Projection* parent2, const string& pname) {
00317 assert(parent2);
00318 return Cmp<Projection>(parent1.getProjection(pname), parent2->getProjection(pname));
00319 }
00320
00321
00322
00323 inline Cmp<Projection> pcmp(const Projection* parent1, const Projection* parent2, const string& pname) {
00324 assert(parent1);
00325 assert(parent2);
00326 return Cmp<Projection>(parent1->getProjection(pname), parent2->getProjection(pname));
00327 }
00328
00329
00330 }
00331
00332
00333 #endif