Imported Upstream version 1.72.0
[platform/upstream/boost.git] / boost / histogram / detail / at.hpp
1 // Copyright 2015-2018 Hans Dembinski
2 //
3 // Distributed under the Boost Software License, Version 1.0.
4 // (See accompanying file LICENSE_1_0.txt
5 // or copy at http://www.boost.org/LICENSE_1_0.txt)
6
7 #ifndef BOOST_HISTOGRAM_DETAIL_AT_HPP
8 #define BOOST_HISTOGRAM_DETAIL_AT_HPP
9
10 #include <boost/histogram/axis/option.hpp>
11 #include <boost/histogram/axis/traits.hpp>
12 #include <boost/histogram/detail/axes.hpp>
13 #include <boost/histogram/detail/linearize.hpp>
14 #include <boost/histogram/fwd.hpp>
15 #include <boost/mp11/algorithm.hpp>
16 #include <tuple>
17
18 namespace boost {
19 namespace histogram {
20 namespace detail {
21
22 template <class A, class... Us>
23 optional_index at(const A& axes, const std::tuple<Us...>& args) noexcept {
24   optional_index idx{0}; // offset not used by linearize_index
25   mp11::mp_for_each<mp11::mp_iota_c<sizeof...(Us)>>(
26       [&, stride = static_cast<std::size_t>(1)](auto i) mutable {
27         stride *= linearize_index(idx, stride, axis_get<i>(axes),
28                                   static_cast<axis::index_type>(std::get<i>(args)));
29       });
30   return idx;
31 }
32
33 template <class A, class U>
34 optional_index at(const A& axes, const U& args) noexcept {
35   optional_index idx{0};
36   using std::begin;
37   for_each_axis(axes, [&, it = begin(args),
38                        stride = static_cast<std::size_t>(1)](const auto& a) mutable {
39     stride *= linearize_index(idx, stride, a, static_cast<axis::index_type>(*it++));
40   });
41   return idx;
42 }
43
44 } // namespace detail
45 } // namespace histogram
46 } // namespace boost
47
48 #endif