// Copyright 2019 Hans Dembinski // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_HISTOGRAM_DETAIL_ACCUMULATOR_TRAITS_HPP #define BOOST_HISTOGRAM_DETAIL_ACCUMULATOR_TRAITS_HPP #include #include #include #include namespace boost { // forward declare accumulator_set so that it can be matched below namespace accumulators { template struct accumulator_set; } namespace histogram { namespace detail { template struct accumulator_traits_holder { static constexpr bool weight_support = WeightSupport; using args = std::tuple; }; // member function pointer with weight_type as first argument is better match template accumulator_traits_holder accumulator_traits_impl_call_op( R (T::*)(boost::histogram::weight_type, Ts...)); template accumulator_traits_holder accumulator_traits_impl_call_op( R (T::*)(boost::histogram::weight_type&, Ts...)); template accumulator_traits_holder accumulator_traits_impl_call_op( R (T::*)(boost::histogram::weight_type&&, Ts...)); template accumulator_traits_holder accumulator_traits_impl_call_op( R (T::*)(const boost::histogram::weight_type&, Ts...)); // member function pointer only considered if all specializations above fail template accumulator_traits_holder accumulator_traits_impl_call_op(R (T::*)(Ts...)); template auto accumulator_traits_impl(T&, priority<2>) -> decltype(accumulator_traits_impl_call_op(&T::operator())); template auto accumulator_traits_impl(T&, priority<2>) -> decltype(std::declval() += std::declval>(), accumulator_traits_holder{}); // fallback for simple arithmetic types that do not implement adding a weight_type template auto accumulator_traits_impl(T&, priority<1>) -> decltype(std::declval() += 0, accumulator_traits_holder{}); template auto accumulator_traits_impl(T&, priority<0>) -> accumulator_traits_holder; // for boost.accumulators compatibility template accumulator_traits_holder accumulator_traits_impl( boost::accumulators::accumulator_set&, priority<2>) { static_assert(std::is_same::value, "accumulator_set with weights is not directly supported, please use " "a wrapper class that implements the Accumulator concept"); } template using accumulator_traits = decltype(accumulator_traits_impl(std::declval(), priority<2>{})); } // namespace detail } // namespace histogram } // namespace boost #endif