]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/boost/boost/histogram/axis/integer.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / histogram / axis / integer.hpp
index 0403cc6720bb23a44f303697ca0bff1840ef1b9e..7e8bb4437481dc10d7df94cf68968d89a9ec39d9 100644 (file)
@@ -13,6 +13,7 @@
 #include <boost/histogram/axis/option.hpp>
 #include <boost/histogram/detail/convert_integer.hpp>
 #include <boost/histogram/detail/limits.hpp>
+#include <boost/histogram/detail/relaxed_equal.hpp>
 #include <boost/histogram/detail/replace_type.hpp>
 #include <boost/histogram/detail/static_if.hpp>
 #include <boost/histogram/fwd.hpp>
@@ -39,10 +40,11 @@ namespace axis {
  */
 template <class Value, class MetaData, class Options>
 class integer : public iterator_mixin<integer<Value, MetaData, Options>>,
-                public metadata_base<MetaData> {
+                public metadata_base_t<MetaData> {
   // these must be private, so that they are not automatically inherited
   using value_type = Value;
-  using metadata_type = typename metadata_base<MetaData>::metadata_type;
+  using metadata_base = metadata_base_t<MetaData>;
+  using metadata_type = typename metadata_base::metadata_type;
   using options_type =
       detail::replace_default<Options, decltype(option::underflow | option::overflow)>;
 
@@ -76,7 +78,7 @@ public:
    * \param meta     description of the axis.
    */
   integer(value_type start, value_type stop, metadata_type meta = {})
-      : metadata_base<MetaData>(std::move(meta))
+      : metadata_base(std::move(meta))
       , size_(static_cast<index_type>(stop - start))
       , min_(start) {
     if (!(stop >= start))
@@ -94,25 +96,9 @@ public:
 
   /// Return index for value argument.
   index_type index(value_type x) const noexcept {
-    return detail::static_if<std::is_floating_point<value_type>>(
-        [this](const auto z) -> index_type {
-          // need to handle NaN, cannot simply cast to int and call int-implementation
-          if (options_type::test(option::circular)) {
-            if (std::isfinite(z))
-              return static_cast<index_type>(std::floor(z) -
-                                             std::floor(z / this->size()) * this->size());
-          } else if (z < this->size())
-            return z >= 0 ? static_cast<index_type>(z) : -1;
-          return this->size();
-        },
-        [this](const auto z) -> index_type {
-          if (options_type::test(option::circular))
-            return static_cast<index_type>(z - std::floor(float(z) / this->size()) *
-                                                   this->size());
-          if (z < this->size()) return z >= 0 ? z : -1;
-          return this->size();
-        },
-        x - min_);
+    return index_impl(options_type::test(axis::option::circular),
+                      std::is_floating_point<value_type>{},
+                      static_cast<double>(x - min_));
   }
 
   /// Returns index and shift (if axis has grown) for the passed argument.
@@ -174,7 +160,8 @@ public:
 
   template <class V, class M, class O>
   bool operator==(const integer<V, M, O>& o) const noexcept {
-    return size() == o.size() && min_ == o.min_ && metadata_base<MetaData>::operator==(o);
+    return size() == o.size() && min_ == o.min_ &&
+           detail::relaxed_equal{}(this->metadata(), o.metadata());
   }
 
   template <class V, class M, class O>
@@ -190,6 +177,24 @@ public:
   }
 
 private:
+  // axis not circular
+  template <class B>
+  index_type index_impl(std::false_type, B, double z) const noexcept {
+    if (z < size()) return z >= 0 ? static_cast<index_type>(z) : -1;
+    return size();
+  }
+
+  // value_type is integer, axis circular
+  index_type index_impl(std::true_type, std::false_type, double z) const noexcept {
+    return static_cast<index_type>(z - std::floor(z / size()) * size());
+  }
+
+  // value_type is floating point, must handle +/-infinite or nan, axis circular
+  index_type index_impl(std::true_type, std::true_type, double z) const noexcept {
+    if (std::isfinite(z)) return index_impl(std::true_type{}, std::false_type{}, z);
+    return z < size() ? -1 : size();
+  }
+
   index_type size_{0};
   value_type min_{0};