Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:38:10

0001 // Copyright 2018 Hans Dembinski
0002 //
0003 // Distributed under the Boost Software License, Version 1.0.
0004 // (See accompanying file LICENSE_1_0.txt
0005 // or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 
0007 #ifndef BOOST_HISTOGRAM_AXIS_POLYMORPHIC_BIN_HPP
0008 #define BOOST_HISTOGRAM_AXIS_POLYMORPHIC_BIN_HPP
0009 
0010 namespace boost {
0011 namespace histogram {
0012 namespace axis {
0013 
0014 /**
0015   Holds the bin data of an axis::variant.
0016 
0017   The interface is a superset of the axis::interval_view
0018   class. In addition, the object is implicitly convertible to the value type,
0019   returning the equivalent of a call to lower(). For discrete axes, lower() ==
0020   upper(), and width() returns zero.
0021 
0022   This is not a view like axis::interval_view for two reasons.
0023   - Sequential calls to lower() and upper() would have to each loop through
0024     the variant types. This is likely to be slower than filling all the data in
0025     one loop.
0026   - polymorphic_bin may be created from a temporary instance of axis::variant,
0027     like in the call histogram::axis(0). Storing a reference to the axis would
0028     result in a dangling reference. Rather than specialing the code to handle
0029     this, it seems easier to just use a value instead of a view.
0030 */
0031 template <class RealType>
0032 class polymorphic_bin {
0033   using value_type = RealType;
0034 
0035 public:
0036   polymorphic_bin(value_type lower, value_type upper)
0037       : lower_or_value_(lower), upper_(upper) {}
0038 
0039   /// Implicitly convert to bin value (for axis with discrete values).
0040   operator const value_type&() const noexcept { return lower_or_value_; }
0041 
0042   /// Return lower edge of bin.
0043   value_type lower() const noexcept { return lower_or_value_; }
0044   /// Return upper edge of bin.
0045   value_type upper() const noexcept { return upper_; }
0046   /// Return center of bin.
0047   value_type center() const noexcept { return 0.5 * (lower() + upper()); }
0048   /// Return width of bin.
0049   value_type width() const noexcept { return upper() - lower(); }
0050 
0051   template <class BinType>
0052   bool operator==(const BinType& rhs) const noexcept {
0053     return equal_impl(rhs, 0);
0054   }
0055 
0056   template <class BinType>
0057   bool operator!=(const BinType& rhs) const noexcept {
0058     return !operator==(rhs);
0059   }
0060 
0061   /// Return true if bin is discrete.
0062   bool is_discrete() const noexcept { return lower_or_value_ == upper_; }
0063 
0064 private:
0065   bool equal_impl(const polymorphic_bin& rhs, int) const noexcept {
0066     return lower_or_value_ == rhs.lower_or_value_ && upper_ == rhs.upper_;
0067   }
0068 
0069   template <class BinType>
0070   auto equal_impl(const BinType& rhs, decltype(rhs.lower(), 0)) const noexcept {
0071     return lower() == rhs.lower() && upper() == rhs.upper();
0072   }
0073 
0074   template <class BinType>
0075   bool equal_impl(const BinType& rhs, float) const noexcept {
0076     return is_discrete() && static_cast<value_type>(*this) == rhs;
0077   }
0078 
0079   const value_type lower_or_value_, upper_;
0080 };
0081 
0082 } // namespace axis
0083 } // namespace histogram
0084 } // namespace boost
0085 
0086 #endif