Rivet
1.8.0
|
00001 // -*- C++ -*- 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 00026 template <typename T> 00027 class Cmp { 00028 public: 00029 00031 00032 00034 Cmp(const T& t1, const T& t2) 00035 : _value(UNDEFINED), _objects(&t1, &t2) { } 00036 00038 template <typename U> 00039 Cmp(const Cmp<U>& x) 00040 : _value(x), _objects(0, 0) { } 00041 00043 ~Cmp() { }; 00044 00046 template <typename U> 00047 const Cmp<T>& operator=(const Cmp<U>& x) { 00048 _value = x; 00049 return *this; 00050 } 00051 00053 00054 public: 00055 00057 operator CmpState() const { 00058 _compare(); 00059 return _value; 00060 } 00061 00063 operator int() const { 00064 _compare(); 00065 return _value; 00066 } 00067 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 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 00089 mutable CmpState _value; 00090 00092 pair<const T*, const T*> _objects; 00093 00094 }; 00095 00096 00111 template <> 00112 class Cmp<Projection> { 00113 public: 00114 00116 00117 00118 Cmp(const Projection& p1, const Projection& p2) 00119 : _value(UNDEFINED), _objects(&p1, &p2) 00120 { } 00121 00123 template <typename U> 00124 Cmp(const Cmp<U>& x) 00125 : _value(x), _objects(0, 0) 00126 { } 00127 00129 ~Cmp() { }; 00130 00132 template <typename U> 00133 const Cmp<Projection>& operator=(const Cmp<U>& x) { 00134 _value = x; 00135 return *this; 00136 } 00138 00139 public: 00140 00142 operator CmpState() const { 00143 _compare(); 00144 return _value; 00145 } 00146 00147 00149 operator int() const { 00150 _compare(); 00151 return _value; 00152 } 00153 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 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 00183 mutable CmpState _value; 00184 00186 pair<const Projection*, const Projection*> _objects; 00187 00188 }; 00189 00190 00191 00192 00206 template <> 00207 class Cmp<double> { 00208 public: 00209 00211 00212 00213 Cmp(const double p1, const double p2) 00214 : _value(UNDEFINED), _numA(p1), _numB(p2) 00215 { } 00216 00218 template <typename U> 00219 Cmp(const Cmp<U>& x) 00220 : _value(x), _numA(0.0), _numB(0.0) 00221 { } 00222 00224 ~Cmp() { } 00225 00227 template <typename U> 00228 const Cmp<double>& operator=(const Cmp<U>& x) { 00229 _value = x; 00230 return *this; 00231 } 00233 00234 public: 00235 00237 operator CmpState() const { 00238 _compare(); 00239 return _value; 00240 } 00241 00243 operator int() const { 00244 _compare(); 00245 return _value; 00246 } 00247 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 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 00270 mutable CmpState _value; 00271 00273 double _numA, _numB; 00274 00275 }; 00276 00277 00278 00280 00281 00282 00284 template <typename T> 00285 inline Cmp<T> cmp(const T& t1, const T& t2) { 00286 return Cmp<T>(t1, t2); 00287 } 00288 00289 00291 typedef Cmp<Projection> PCmp; 00292 00293 00295 inline Cmp<Projection> pcmp(const Projection& p1, const Projection& p2) { 00296 return Cmp<Projection>(p1, p2); 00297 } 00298 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 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 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 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