From cb85d65489afe4e3970e5c71c2b1351f0ee4fc3b Mon Sep 17 00:00:00 2001 From: Hans Dembinski Date: Thu, 1 Nov 2018 23:44:17 +0100 Subject: [PATCH] simpler --- include/boost/histogram/axis/variant.hpp | 4 +- include/boost/histogram/detail/axes.hpp | 80 +++++++----------------- include/boost/histogram/histogram.hpp | 10 +-- 3 files changed, 32 insertions(+), 62 deletions(-) diff --git a/include/boost/histogram/axis/variant.hpp b/include/boost/histogram/axis/variant.hpp index 84ea4507..979d979d 100644 --- a/include/boost/histogram/axis/variant.hpp +++ b/include/boost/histogram/axis/variant.hpp @@ -156,8 +156,8 @@ public: [&x](const auto& a) { using A = detail::unqual; using expected_t = axis::traits::arg; - return detail::static_if, expected_t>>( - [&x](const auto& a) -> int { return a(static_cast(x)); }, + return detail::static_if>( + [&x](const auto& a) -> int { return a(x); }, [](const auto&) -> int { throw std::invalid_argument(detail::cat( "cannot convert ", boost::core::demangled_name(BOOST_CORE_TYPEID(U)), diff --git a/include/boost/histogram/detail/axes.hpp b/include/boost/histogram/detail/axes.hpp index 180eb990..a1909040 100644 --- a/include/boost/histogram/detail/axes.hpp +++ b/include/boost/histogram/detail/axes.hpp @@ -305,47 +305,12 @@ inline void linearize(optional_index& out, const int axis_size, const int axis_s out.stride *= (j < axis_shape) * axis_shape; // set to 0, if j is invalid } -template -void indices_to_index(optional_index&, const Axes&) noexcept {} - -template -void indices_to_index(optional_index& idx, const Axes& axes, const int j, - const Us... us) { - const auto& a = axis_get(axes); - const auto a_size = static_cast(a.size()); - const auto a_shape = static_cast(axis::traits::extend(a)); - idx.stride *= (-1 <= j && j <= a_size); // set to 0, if j is invalid - linearize(idx, a_size, a_shape, j); - indices_to_index<(D + 1)>(idx, axes, us...); -} - -template -void indices_to_index_iter(mp11::mp_size_t<0>, optional_index&, const std::tuple&, - Iterator) {} - -template -void indices_to_index_iter(mp11::mp_size_t, optional_index& idx, - const std::tuple& axes, Iterator iter) { - constexpr auto D = mp11::mp_size_t() - N; - const auto& a = std::get(axes); - const auto a_size = static_cast(a.size()); - const auto a_shape = axis::traits::extend(a); - const auto j = static_cast(*iter); - idx.stride *= (-1 <= j && j <= a_size); // set to 0, if j is invalid - linearize(idx, a_size, a_shape, j); - indices_to_index_iter(mp11::mp_size_t<(N - 1)>(), idx, axes, ++iter); -} - -template -void indices_to_index_iter(optional_index& idx, const std::vector& axes, - Iterator iter) { - for (const auto& a : axes) { - const auto a_size = static_cast(a.size()); - const auto a_shape = axis::traits::extend(a); - const auto j = static_cast(*iter++); - idx.stride *= (-1 <= j && j <= a_size); // set to 0, if j is invalid - linearize(idx, a_size, a_shape, j); - } +template +void linearize2(optional_index& out, const T& axis, int j) { + const auto a_size = static_cast(axis.size()); + const auto a_shape = axis::traits::extend(axis); + out.stride *= (-1 <= j && j <= a_size); // set to 0, if j is invalid + linearize(out, a_size, a_shape, j); } template @@ -501,37 +466,40 @@ optional_index call_impl(iterable_container_tag, const std::vector& axes, * the exception and do something sensible. */ -template -optional_index at_impl(no_container_tag, const A& axes, const Us&... us) { - dimension_check(axes, mp11::mp_size_t()); - auto index = detail::optional_index(); - detail::indices_to_index<0>(index, axes, static_cast(us)...); - return index; +template +optional_index at_impl(no_container_tag, const A& axes, const U& u) { + return at_impl(static_container_tag(), axes, std::forward_as_tuple(u)); } template optional_index at_impl(static_container_tag, const A& axes, const U& u) { - return mp11::tuple_apply( - [&axes](const auto&... us) { return at_impl(no_container_tag(), axes, us...); }, u); + dimension_check(axes, mp11::mp_size>()); + detail::optional_index idx; + mp11::mp_for_each>>([&](auto I) { + linearize2(idx, axis_get(axes), static_cast(std::get(u))); + }); + return idx; } template optional_index at_impl(iterable_container_tag, const std::tuple& axes, const U& u) { dimension_check(axes, std::distance(std::begin(u), std::end(u))); - auto index = detail::optional_index(); - detail::indices_to_index_iter(mp11::mp_size_t(), index, axes, - std::begin(u)); - return index; + detail::optional_index idx; + auto xit = std::begin(u); + mp11::mp_for_each>( + [&](auto I) { linearize2(idx, std::get(axes), static_cast(*xit++)); }); + return idx; } template optional_index at_impl(iterable_container_tag, const std::vector& axes, const U& u) { dimension_check(axes, std::distance(std::begin(u), std::end(u))); - auto index = detail::optional_index(); - detail::indices_to_index_iter(index, axes, std::begin(u)); - return index; + detail::optional_index idx; + auto xit = std::begin(u); + for (const auto& a : axes) linearize2(idx, a, static_cast(*xit++)); + return idx; } } // namespace detail diff --git a/include/boost/histogram/histogram.hpp b/include/boost/histogram/histogram.hpp index 203431d3..b7b0b3dd 100644 --- a/include/boost/histogram/histogram.hpp +++ b/include/boost/histogram/histogram.hpp @@ -148,7 +148,8 @@ public: template void operator()(const Ts&... ts) { // case with one argument needs special treatment, specialized below - const auto index = detail::call_impl(detail::no_container_tag(), axes_, ts...); + const auto index = detail::call_impl(detail::static_container_tag(), axes_, + std::forward_as_tuple(ts...)); if (index) storage_(*index); } @@ -163,7 +164,8 @@ public: template void operator()(const weight_type& w, const Ts&... ts) { // case with one argument needs special treatment, specialized below - const auto index = detail::call_impl(detail::no_container_tag(), axes_, ts...); + const auto index = detail::call_impl(detail::static_container_tag(), axes_, + std::forward_as_tuple(ts...)); if (index) storage_(*index, w); } @@ -178,8 +180,8 @@ public: template const_reference at(const Ts&... ts) const { // case with one argument is ambiguous, is specialized below - const auto index = - detail::at_impl(detail::no_container_tag(), axes_, static_cast(ts)...); + const auto index = detail::at_impl(detail::static_container_tag(), axes_, + std::forward_as_tuple(static_cast(ts)...)); if (!index) throw std::out_of_range("indices out of bounds"); return storage_[*index]; }