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