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