Cmp.hh
Go to the documentation of this file.
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 00014 /// Helper class when checking the ordering of two objects. 00015 /// 00016 /// Cmp is a helper class to be used when checking the ordering of two 00017 /// objects. When implicitly converted to an integer the value will be 00018 /// negative if the two objects used in the constructor are ordered and 00019 /// positive if they are not. Zero will be returned if they are equal. 00020 /// 00021 /// The main usage of the Cmp class is if several variables should be 00022 /// checked for ordering in which case several Cmp objects can be 00023 /// combined as follows: <code>cmp(a1, a2) || cmp(b1, b2) || cmp(c1, 00024 /// c2)</code> where cmp is a global function for easy creation of Cmp 00025 /// objects. 00026 template <typename T> 00027 class Cmp { 00028 public: 00029 00030 /// @name Standard constructors etc. 00031 //@{ 00032 00033 /// The default constructor. 00034 Cmp(const T& t1, const T& t2) 00035 : _value(UNDEFINED), _objects(&t1, &t2) { } 00036 00037 /// The copy constructor. 00038 template <typename U> 00039 Cmp(const Cmp<U>& x) 00040 : _value(x), _objects(0, 0) { } 00041 00042 /// The destructor is not virtual since this is not intended to be a base class. 00043 ~Cmp() { }; 00044 00045 /// The assignment operator. 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 /// Automatically convert to an enum. 00057 operator CmpState() const { 00058 _compare(); 00059 return _value; 00060 } 00061 00062 /// Automatically convert to an integer. 00063 operator int() const { 00064 _compare(); 00065 return _value; 00066 } 00067 00068 /// If this state is equivalent, set this state to the state of \a c. 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 /// Perform the actual comparison if necessary. 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 /// The state of this object. 00089 mutable CmpState _value; 00090 00091 /// The objects to be compared. 00092 pair<const T*, const T*> _objects; 00093 00094 }; 00095 00096 00097 /// @brief Specialization of Cmp for checking the ordering of two @a {Projection}s. 00098 /// 00099 /// Specialization of the Cmp helper class to be used when checking the 00100 /// ordering of two Projection objects. When implicitly converted to an 00101 /// integer the value will be negative if the two objects used in the 00102 /// constructor are ordered and positive if they are not. Zero will be 00103 /// returned if they are equal. This specialization uses directly the 00104 /// virtual compare() function in the Projection class. 00105 /// 00106 /// The main usage of the Cmp class is if several variables should be 00107 /// checked for ordering in which case several Cmp objects can be 00108 /// combined as follows: <code>cmp(a1, a2) || cmp(b1, b2) || cmp(c1, 00109 /// c2)</code> where cmp is a global function for easy creation of Cmp 00110 /// objects. 00111 template <> 00112 class Cmp<Projection> { 00113 public: 00114 00115 /// @name Standard constructors and destructors. 00116 //@{ 00117 /// The default constructor. 00118 Cmp(const Projection& p1, const Projection& p2) 00119 : _value(UNDEFINED), _objects(&p1, &p2) 00120 { } 00121 00122 /// The copy constructor. 00123 template <typename U> 00124 Cmp(const Cmp<U>& x) 00125 : _value(x), _objects(0, 0) 00126 { } 00127 00128 /// The destructor is not virtual since this is not intended to be a base class. 00129 ~Cmp() { }; 00130 00131 /// The assignment operator. 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 /// Automatically convert to an enum. 00142 operator CmpState() const { 00143 _compare(); 00144 return _value; 00145 } 00146 00147 00148 /// Automatically convert to an integer. 00149 operator int() const { 00150 _compare(); 00151 return _value; 00152 } 00153 00154 /// If this state is equivalent, set this state to the state of \a c. 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 /// Perform the actual comparison if necessary. 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 /// The state of this object. 00183 mutable CmpState _value; 00184 00185 /// The objects to be compared. 00186 pair<const Projection*, const Projection*> _objects; 00187 00188 }; 00189 00190 00191 00192 00193 /// @brief Specialization of Cmp for checking the ordering of two floating point numbers. 00194 /// 00195 /// When implicitly converted to an integer the value will be negative if the 00196 /// two objects used in the constructor are ordered and positive if they are 00197 /// not. Zero will be returned if they are equal. This specialization uses the 00198 /// Rivet fuzzyEquals function to indicate equivalence protected from 00199 /// numerical precision effects. 00200 /// 00201 /// The main usage of the Cmp class is if several variables should be 00202 /// checked for ordering in which case several Cmp objects can be 00203 /// combined as follows: <code>cmp(a1, a2) || cmp(b1, b2) || cmp(c1, 00204 /// c2)</code> where cmp is a global function for easy creation of Cmp 00205 /// objects. 00206 template <> 00207 class Cmp<double> { 00208 public: 00209 00210 /// @name Standard constructors and destructors. 00211 //@{ 00212 /// The default constructor. 00213 Cmp(const double p1, const double p2) 00214 : _value(UNDEFINED), _numA(p1), _numB(p2) 00215 { } 00216 00217 /// The copy constructor. 00218 template <typename U> 00219 Cmp(const Cmp<U>& x) 00220 : _value(x), _numA(0.0), _numB(0.0) 00221 { } 00222 00223 /// The destructor is not virtual since this is not intended to be a base class. 00224 ~Cmp() { } 00225 00226 /// The assignment operator. 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 /// Automatically convert to an enum. 00237 operator CmpState() const { 00238 _compare(); 00239 return _value; 00240 } 00241 00242 /// Automatically convert to an integer. 00243 operator int() const { 00244 _compare(); 00245 return _value; 00246 } 00247 00248 /// If this state is equivalent, set this state to the state of \a c. 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 /// Perform the actual comparison if necessary. 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 /// The state of this object. 00270 mutable CmpState _value; 00271 00272 /// The objects to be compared. 00273 double _numA, _numB; 00274 00275 }; 00276 00277 00278 00279 /////////////////////////////////////////////////////////////////// 00280 00281 00282 00283 /// Global helper function for easy creation of Cmp objects. 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 /// Typedef for Cmp<Projection> 00291 typedef Cmp<Projection> PCmp; 00292 00293 00294 /// Global helper function for easy creation of Cmp<Projection> objects. 00295 inline Cmp<Projection> pcmp(const Projection& p1, const Projection& p2) { 00296 return Cmp<Projection>(p1, p2); 00297 } 00298 00299 /// Global helper function for easy creation of Cmp<Projection> objects from 00300 /// two parent projections and their common name for the projection to be compared. 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 /// Global helper function for easy creation of Cmp<Projection> objects from 00306 /// two parent projections and their common name for the projection to be compared. 00307 /// This version takes one parent as a pointer. 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 /// Global helper function for easy creation of Cmp<Projection> objects from 00314 /// two parent projections and their common name for the projection to be compared. 00315 /// This version takes one parent as a pointer. 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 /// Global helper function for easy creation of Cmp<Projection> objects from 00322 /// two parent projections and their common name for the projection to be compared. 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 Generated on Fri Dec 21 2012 15:03:40 for The Rivet MC analysis system by ![]() |