File indexing completed on 2025-01-18 09:38:11
0001
0002
0003
0004
0005
0006
0007 #ifndef BOOST_HISTOGRAM_DETAIL_ARGUMENT_TRAITS_HPP
0008 #define BOOST_HISTOGRAM_DETAIL_ARGUMENT_TRAITS_HPP
0009
0010 #include <boost/histogram/fwd.hpp>
0011 #include <boost/mp11/algorithm.hpp>
0012 #include <boost/mp11/integral.hpp>
0013 #include <boost/mp11/list.hpp>
0014 #include <tuple>
0015
0016 namespace boost {
0017 namespace histogram {
0018 namespace detail {
0019
0020 template <class T>
0021 struct is_weight_impl : mp11::mp_false {};
0022
0023 template <class T>
0024 struct is_weight_impl<weight_type<T>> : mp11::mp_true {};
0025
0026 template <class T>
0027 using is_weight = is_weight_impl<T>;
0028
0029 template <class T>
0030 struct is_sample_impl : mp11::mp_false {};
0031
0032 template <class T>
0033 struct is_sample_impl<sample_type<T>> : mp11::mp_true {};
0034
0035 template <class T>
0036 using is_sample = is_sample_impl<T>;
0037
0038 template <int Idx, class L>
0039 struct sample_args_impl {
0040 using type = mp11::mp_first<std::decay_t<mp11::mp_at_c<L, (Idx >= 0 ? Idx : 0)>>>;
0041 };
0042
0043 template <class L>
0044 struct sample_args_impl<-1, L> {
0045 using type = std::tuple<>;
0046 };
0047
0048 template <std::size_t NArgs, std::size_t Start, int WeightPos, int SamplePos,
0049 class SampleArgs>
0050 struct argument_traits_holder {
0051 using nargs = mp11::mp_size_t<NArgs>;
0052 using start = mp11::mp_size_t<Start>;
0053 using wpos = mp11::mp_int<WeightPos>;
0054 using spos = mp11::mp_int<SamplePos>;
0055 using sargs = SampleArgs;
0056 };
0057
0058 template <class... Ts>
0059 struct argument_traits_impl {
0060 using list_ = mp11::mp_list<Ts...>;
0061 static constexpr std::size_t size_ = sizeof...(Ts);
0062 static constexpr std::size_t weight_ = mp11::mp_find_if<list_, is_weight>::value;
0063 static constexpr std::size_t sample_ = mp11::mp_find_if<list_, is_sample>::value;
0064 static constexpr int spos_ = (sample_ < size_ ? static_cast<int>(sample_) : -1);
0065 static constexpr int wpos_ = (weight_ < size_ ? static_cast<int>(weight_) : -1);
0066
0067 using type =
0068 argument_traits_holder<(size_ - (weight_ < size_) - (sample_ < size_)),
0069 (weight_ < size_ && sample_ < size_ &&
0070 (weight_ + sample_ < 2)
0071 ? 2
0072 : ((weight_ == 0 || sample_ == 0) ? 1 : 0)),
0073 wpos_, spos_, typename sample_args_impl<spos_, list_>::type>;
0074 };
0075
0076 template <class... Ts>
0077 using argument_traits = typename argument_traits_impl<Ts...>::type;
0078
0079 }
0080 }
0081 }
0082
0083 #endif