Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-04-19 09:06:50

0001 // -*- C++ -*-
0002 #ifndef RIVET_Cmp_HH
0003 #define RIVET_Cmp_HH
0004 
0005 #include "Rivet/Config/RivetCommon.hh"
0006 #include "Rivet/Projection.hh"
0007 #include "Cmp.fhh"
0008 #include <typeinfo>
0009 
0010 
0011 namespace Rivet {
0012 
0013 
0014   /// Helper class when checking the ordering of two objects.
0015   ///
0016   /// Cmp is a helper class to be used when checking the ordering of two
0017   /// objects. When implicitly converted to an integer the value will be
0018   /// negative if the two objects used in the constructor are ordered and
0019   /// positive if they are not. Zero will be returned if they are equal.
0020   ///
0021   /// The main usage of the Cmp class is if several variables should be
0022   /// checked for ordering in which case several Cmp objects can be
0023   /// combined as follows: <code>cmp(a1, a2) || cmp(b1, b2) || cmp(c1,
0024   /// c2)</code> where cmp is a global function for easy creation of Cmp
0025   /// objects.
0026   template <typename T>
0027   class Cmp final {
0028   public:
0029 
0030     /// @name Standard constructors etc.
0031     /// @{
0032 
0033     /// The default constructor.
0034     Cmp(const T& t1, const T& t2)
0035       : _value(CmpState::UNDEF), _objects(&t1, &t2) { }
0036 
0037     /// The copy constructor.
0038     template <typename U>
0039     Cmp(const Cmp<U>& x)
0040       : _value(x._value), _objects(nullptr, nullptr) { }
0041 
0042     /// The assignment operator.
0043     template <typename U>
0044     const Cmp<T>& operator=(const Cmp<U>& x) {
0045       _value = x;
0046       return *this;
0047     }
0048 
0049     /// @}
0050 
0051   public:
0052 
0053     /// Automatically convert to an enum.
0054     operator CmpState() const {
0055       _compare();
0056       return _value;
0057     }
0058 
0059     /// If this state is equivalent, set this state to the state of \a c.
0060     template <typename U>
0061     const Cmp<T>& operator||(const Cmp<U>& c) const {
0062       _compare();
0063       if (_value == CmpState::EQ) _value = c;
0064       return *this;
0065     }
0066 
0067   private:
0068 
0069     /// Perform the actual comparison if necessary.
0070     void _compare() const {
0071       if (_value == CmpState::UNDEF) {
0072         std::less<T> l;
0073         if ( l(*_objects.first, *_objects.second) )       _value = CmpState::NEQ;
0074         else if ( l(*_objects.second, *_objects.first) )  _value = CmpState::NEQ;
0075         else _value = CmpState::EQ;
0076       }
0077     }
0078 
0079     /// The state of this object.
0080     mutable CmpState _value;
0081 
0082     /// The objects to be compared.
0083     const pair<const T*, const T*> _objects;
0084 
0085   };
0086 
0087 
0088   /// @brief Specialization of Cmp for checking the ordering of two @a {Projection}s.
0089   ///
0090   /// Specialization of the Cmp helper class to be used when checking the
0091   /// ordering of two Projection objects. When implicitly converted to an
0092   /// integer the value will be negative if the two objects used in the
0093   /// constructor are ordered and positive if they are not. Zero will be
0094   /// returned if they are equal. This specialization uses directly the
0095   /// virtual compare() function in the Projection class.
0096   ///
0097   /// The main usage of the Cmp class is if several variables should be
0098   /// checked for ordering in which case several Cmp objects can be
0099   /// combined as follows: <code>cmp(a1, a2) || cmp(b1, b2) || cmp(c1,
0100   /// c2)</code> where cmp is a global function for easy creation of Cmp
0101   /// objects.
0102   template <>
0103   class Cmp<Projection> final {
0104   public:
0105 
0106     /// @name Standard constructors and destructors.
0107     /// @{
0108     /// The default constructor.
0109     Cmp(const Projection& p1, const Projection& p2)
0110       : _value(CmpState::UNDEF), _objects(&p1, &p2)
0111     { }
0112 
0113     /// The copy constructor.
0114     template <typename U>
0115     Cmp(const Cmp<U>& x)
0116       : _value(x), _objects(nullptr, nullptr)
0117     { }
0118 
0119     /// The assignment operator.
0120     template <typename U>
0121     const Cmp<Projection>& operator=(const Cmp<U>& x) {
0122       _value = x;
0123       return *this;
0124     }
0125     /// @}
0126 
0127   public:
0128 
0129     /// Automatically convert to an enum.
0130     operator CmpState() const {
0131       _compare();
0132       return _value;
0133     }
0134 
0135     /// If this state is equivalent, set this state to the state of \a c.
0136     template <typename U>
0137     const Cmp<Projection>& operator||(const Cmp<U>& c) const {
0138       _compare();
0139       if (_value == CmpState::EQ) _value = c;
0140       return *this;
0141     }
0142 
0143   private:
0144 
0145     /// Perform the actual comparison if necessary.
0146     void _compare() const {
0147       if (_value == CmpState::UNDEF) {
0148         const std::type_info& id1 = typeid(*_objects.first);
0149         const std::type_info& id2 = typeid(*_objects.second);
0150         if (id1.before(id2))       _value = CmpState::NEQ;
0151         else if (id2.before(id1))  _value = CmpState::NEQ;
0152         else {
0153           CmpState cmps = _objects.first->compare(*_objects.second);
0154           if (cmps == CmpState::EQ)  _value = CmpState::EQ;
0155           else                       _value = CmpState::NEQ;
0156         }
0157       }
0158     }
0159 
0160   private:
0161 
0162     /// The state of this object.
0163     mutable CmpState _value;
0164 
0165     /// The objects to be compared.
0166     const pair<const Projection*, const Projection*> _objects;
0167 
0168   };
0169 
0170 
0171 
0172 
0173   /// @brief Specialization of Cmp for checking the ordering of two floating point numbers.
0174   ///
0175   /// When implicitly converted to an integer the value will be negative if the
0176   /// two objects used in the constructor are ordered and positive if they are
0177   /// not. Zero will be returned if they are equal. This specialization uses the
0178   /// Rivet fuzzyEquals function to indicate equivalence protected from
0179   /// numerical precision effects.
0180   ///
0181   /// The main usage of the Cmp class is if several variables should be
0182   /// checked for ordering in which case several Cmp objects can be
0183   /// combined as follows: <code>cmp(a1, a2) || cmp(b1, b2) || cmp(c1,
0184   /// c2)</code> where cmp is a global function for easy creation of Cmp
0185   /// objects.
0186   template <>
0187   class Cmp<double> final {
0188   public:
0189 
0190     /// @name Standard constructors and destructors.
0191     /// @{
0192     /// The default constructor.
0193     Cmp(const double p1, const double p2)
0194       : _value(CmpState::UNDEF), _numA(p1), _numB(p2)
0195     { }
0196 
0197     /// The copy constructor.
0198     template <typename U>
0199     Cmp(const Cmp<U>& x)
0200       : _value(x), _numA(0.0), _numB(0.0)
0201     { }
0202 
0203     /// The assignment operator.
0204     template <typename U>
0205     const Cmp<double>& operator=(const Cmp<U>& x) {
0206       _value = x;
0207       return *this;
0208     }
0209     /// @}
0210 
0211   public:
0212 
0213     /// Automatically convert to an enum.
0214     operator CmpState() const {
0215       _compare();
0216       return _value;
0217     }
0218 
0219     /// If this state is equivalent, set this state to the state of \a c.
0220     template <typename U>
0221     const Cmp<double>& operator||(const Cmp<U>& c) const {
0222       _compare();
0223       if (_value == CmpState::EQ) _value = c;
0224       return *this;
0225     }
0226 
0227   private:
0228 
0229     /// Perform the actual comparison if necessary.
0230     void _compare() const {
0231       if (_value == CmpState::UNDEF) {
0232         if (fuzzyEquals(_numA,_numB)) _value = CmpState::EQ;
0233         else _value = CmpState::NEQ;
0234       }
0235     }
0236 
0237   private:
0238 
0239     /// The state of this object.
0240     mutable CmpState _value;
0241 
0242     /// The objects to be compared.
0243     const double _numA, _numB;
0244 
0245   };
0246 
0247 
0248 
0249   ///////////////////////////////////////////////////////////////////
0250 
0251 
0252 
0253   /// Global helper function for easy creation of Cmp objects.
0254   template <typename T>
0255   inline Cmp<T> cmp(const T& t1, const T& t2) {
0256     return Cmp<T>(t1, t2);
0257   }
0258 
0259 
0260   /// Typedef for Cmp<Projection>
0261   using PCmp = Cmp<Projection>;
0262 
0263 
0264   /// Global helper function for easy creation of Cmp<Projection> objects.
0265   inline Cmp<Projection> pcmp(const Projection& p1, const Projection& p2) {
0266     return Cmp<Projection>(p1, p2);
0267   }
0268 
0269   /// Global helper function for easy creation of Cmp<Projection> objects from
0270   /// two parent projections and their common name for the projection to be compared.
0271   inline Cmp<Projection> pcmp(const Projection& parent1, const Projection& parent2, const string& pname) {
0272     return Cmp<Projection>(parent1.getProjection(pname), parent2.getProjection(pname));
0273   }
0274 
0275   /// Global helper function for easy creation of Cmp<Projection> objects from
0276   /// two parent projections and their common name for the projection to be compared.
0277   /// This version takes one parent as a pointer.
0278   inline Cmp<Projection> pcmp(const Projection* parent1, const Projection& parent2, const string& pname) {
0279     assert(parent1);
0280     return Cmp<Projection>(parent1->getProjection(pname), parent2.getProjection(pname));
0281   }
0282 
0283   /// Global helper function for easy creation of Cmp<Projection> objects from
0284   /// two parent projections and their common name for the projection to be compared.
0285   /// This version takes one parent as a pointer.
0286   inline Cmp<Projection> pcmp(const Projection& parent1, const Projection* parent2, const string& pname) {
0287     assert(parent2);
0288     return Cmp<Projection>(parent1.getProjection(pname), parent2->getProjection(pname));
0289   }
0290 
0291   /// Global helper function for easy creation of Cmp<Projection> objects from
0292   /// two parent projections and their common name for the projection to be compared.
0293   inline Cmp<Projection> pcmp(const Projection* parent1, const Projection* parent2, const string& pname) {
0294     assert(parent1);
0295     assert(parent2);
0296     return Cmp<Projection>(parent1->getProjection(pname), parent2->getProjection(pname));
0297   }
0298 
0299 
0300 }
0301 
0302 
0303 #endif