Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-14 10:31:08

0001 /// \file
0002 /// \warning This is part of the %ROOT 7 prototype! It will change without notice. It might trigger earthquakes.
0003 /// Feedback is welcome!
0004 
0005 #ifndef ROOT_RBinIndex
0006 #define ROOT_RBinIndex
0007 
0008 #include <cassert>
0009 #include <cstddef>
0010 
0011 namespace ROOT {
0012 namespace Experimental {
0013 
0014 /**
0015 A bin index with special values for underflow and overflow bins.
0016 
0017 Objects of this type should be passed by value.
0018 
0019 \warning This is part of the %ROOT 7 prototype! It will change without notice. It might trigger earthquakes.
0020 Feedback is welcome!
0021 */
0022 class RBinIndex final {
0023    static constexpr std::size_t UnderflowIndex = -3;
0024    static constexpr std::size_t OverflowIndex = -2;
0025    static constexpr std::size_t InvalidIndex = -1;
0026 
0027    std::size_t fIndex = InvalidIndex;
0028 
0029 public:
0030    /// Construct an invalid bin index.
0031    RBinIndex() = default;
0032 
0033    /// Construct a bin index for a normal bin.
0034    RBinIndex(std::size_t index) : fIndex(index) { assert(IsNormal()); }
0035 
0036    /// Return the index for a normal bin.
0037    std::size_t GetIndex() const
0038    {
0039       assert(IsNormal());
0040       return fIndex;
0041    }
0042 
0043    /// A bin index is normal iff it is not one of the special values.
0044    ///
0045    /// Note that a normal bin index may not actually be valid for a given axis if it is outside its range.
0046    bool IsNormal() const { return fIndex < UnderflowIndex; }
0047    bool IsUnderflow() const { return fIndex == UnderflowIndex; }
0048    bool IsOverflow() const { return fIndex == OverflowIndex; }
0049    bool IsInvalid() const { return fIndex == InvalidIndex; }
0050 
0051    RBinIndex &operator+=(std::size_t a)
0052    {
0053       if (!IsNormal()) {
0054          // Arithmetic operations on special values go to InvalidIndex.
0055          fIndex = InvalidIndex;
0056       } else {
0057          std::size_t old = fIndex;
0058          fIndex += a;
0059          if (fIndex < old || !IsNormal()) {
0060             // The addition wrapped around, go to InvalidIndex.
0061             fIndex = InvalidIndex;
0062          }
0063       }
0064       return *this;
0065    }
0066 
0067    RBinIndex operator+(std::size_t a) const
0068    {
0069       RBinIndex ret = *this;
0070       ret += a;
0071       return ret;
0072    }
0073 
0074    RBinIndex &operator++()
0075    {
0076       operator+=(1);
0077       return *this;
0078    }
0079 
0080    RBinIndex operator++(int)
0081    {
0082       RBinIndex old = *this;
0083       operator++();
0084       return old;
0085    }
0086 
0087    RBinIndex &operator-=(std::size_t a)
0088    {
0089       if (!IsNormal()) {
0090          // Arithmetic operations on special values go to InvalidIndex.
0091          fIndex = InvalidIndex;
0092       } else if (fIndex >= a) {
0093          fIndex -= a;
0094       } else {
0095          // The operation would wrap around, go to InvalidIndex.
0096          fIndex = InvalidIndex;
0097       }
0098       return *this;
0099    }
0100 
0101    RBinIndex operator-(std::size_t a) const
0102    {
0103       RBinIndex ret = *this;
0104       ret -= a;
0105       return ret;
0106    }
0107 
0108    RBinIndex &operator--()
0109    {
0110       operator-=(1);
0111       return *this;
0112    }
0113 
0114    RBinIndex operator--(int)
0115    {
0116       RBinIndex old = *this;
0117       operator--();
0118       return old;
0119    }
0120 
0121    friend bool operator==(RBinIndex lhs, RBinIndex rhs) { return lhs.fIndex == rhs.fIndex; }
0122    friend bool operator!=(RBinIndex lhs, RBinIndex rhs) { return !(lhs == rhs); }
0123 
0124    friend bool operator<(RBinIndex lhs, RBinIndex rhs)
0125    {
0126       if (lhs.IsNormal() && rhs.IsNormal()) {
0127          return lhs.fIndex < rhs.fIndex;
0128       }
0129       return false;
0130    }
0131    friend bool operator<=(RBinIndex lhs, RBinIndex rhs) { return lhs == rhs || lhs < rhs; }
0132 
0133    friend bool operator>(RBinIndex lhs, RBinIndex rhs)
0134    {
0135       if (lhs.IsNormal() && rhs.IsNormal()) {
0136          return lhs.fIndex > rhs.fIndex;
0137       }
0138       return false;
0139    }
0140    friend bool operator>=(RBinIndex lhs, RBinIndex rhs) { return lhs == rhs || lhs > rhs; }
0141 
0142    static RBinIndex Underflow()
0143    {
0144       RBinIndex underflow;
0145       underflow.fIndex = UnderflowIndex;
0146       return underflow;
0147    }
0148 
0149    static RBinIndex Overflow()
0150    {
0151       RBinIndex overflow;
0152       overflow.fIndex = OverflowIndex;
0153       return overflow;
0154    }
0155 };
0156 
0157 } // namespace Experimental
0158 } // namespace ROOT
0159 
0160 #endif