From 3a7c8cb71501eae55099c494c78e90b305deeadd Mon Sep 17 00:00:00 2001 From: Hans Dembinski Date: Sun, 11 Mar 2018 20:51:03 +0100 Subject: [PATCH] always return matching types in bin_views --- include/boost/histogram/axis/axis.hpp | 2 +- include/boost/histogram/axis/bin_view.hpp | 6 +++--- include/boost/histogram/axis/ostream_operators.hpp | 2 +- include/boost/histogram/detail/meta.hpp | 11 +++++++++++ src/python/axis.cpp | 5 +---- 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/include/boost/histogram/axis/axis.hpp b/include/boost/histogram/axis/axis.hpp index 87f7be79..7aec7abd 100644 --- a/include/boost/histogram/axis/axis.hpp +++ b/include/boost/histogram/axis/axis.hpp @@ -552,7 +552,7 @@ public: } /// Returns the value for the bin index (performs a range check). - inline value_type value(int idx) const { + inline const value_type& value(int idx) const { auto it = map_->right.find(idx); if (it == map_->right.end()) throw std::out_of_range("category index out of range"); diff --git a/include/boost/histogram/axis/bin_view.hpp b/include/boost/histogram/axis/bin_view.hpp index ce9b6e3b..5d672d0d 100644 --- a/include/boost/histogram/axis/bin_view.hpp +++ b/include/boost/histogram/axis/bin_view.hpp @@ -26,8 +26,8 @@ public: int idx() const noexcept { return idx_; } - typename Axis::value_type lower() const noexcept { return axis_.lower(idx_); } - typename Axis::value_type upper() const noexcept { return axis_.lower(idx_+1); } + auto lower() const noexcept -> decltype(std::declval().lower(0)) { return axis_.lower(idx_); } + auto upper() const noexcept -> decltype(std::declval().lower(0)) { return axis_.lower(idx_+1); } typename Axis::value_type width() const noexcept { return upper() - lower(); } bool operator==(const interval_view &rhs) const noexcept { @@ -56,7 +56,7 @@ public: int idx() const noexcept { return idx_; } - typename Axis::value_type value() const { + auto value() const -> decltype(std::declval().value(0)) { return axis_.value(idx_); } diff --git a/include/boost/histogram/axis/ostream_operators.hpp b/include/boost/histogram/axis/ostream_operators.hpp index 6be6d7dc..73b632de 100644 --- a/include/boost/histogram/axis/ostream_operators.hpp +++ b/include/boost/histogram/axis/ostream_operators.hpp @@ -137,7 +137,7 @@ inline std::ostream &operator<<(std::ostream &os, const category &a) { os << "category("; for (int i = 0; i < a.size(); ++i) { - ::boost::histogram::detail::escape(os, a[i].value()); + ::boost::histogram::detail::escape(os, a.value(i)); os << (i == (a.size() - 1) ? "" : ", "); } if (!a.label().empty()) { diff --git a/include/boost/histogram/detail/meta.hpp b/include/boost/histogram/detail/meta.hpp index 691e325b..be75a7d9 100644 --- a/include/boost/histogram/detail/meta.hpp +++ b/include/boost/histogram/detail/meta.hpp @@ -47,6 +47,17 @@ template struct has_variance_support { template using has_variance_support_t = typename has_variance_support::type; +template struct has_method_lower { + template ().lower(0))> + struct SFINAE {}; + template static std::true_type Test(SFINAE *); + template static std::false_type Test(...); + using type = decltype(Test(nullptr)); +}; + +template +using has_method_lower_t = typename has_method_lower::type; + template (), ++std::declval())> struct is_iterator {}; diff --git a/src/python/axis.cpp b/src/python/axis.cpp index 736e5d23..9a0f8c50 100644 --- a/src/python/axis.cpp +++ b/src/python/axis.cpp @@ -153,10 +153,7 @@ template bp::object axis_getitem(const A &a, int i) { PyErr_SetString(PyExc_IndexError, "index out of bounds"); bp::throw_error_already_set(); } - return axis_getitem_impl(std::is_same< - typename A::bin_type, bha::interval_view - >(), a, i); - return bp::object(); + return axis_getitem_impl(bh::detail::has_method_lower_t(), a, i); } template void axis_set_label(T& t, bp::str s) {