Imported Upstream version 1.72.0
[platform/upstream/boost.git] / boost / histogram / detail / accumulator_traits.hpp
1 // Copyright 2019 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_ACCUMULATOR_TRAITS_HPP
8 #define BOOST_HISTOGRAM_DETAIL_ACCUMULATOR_TRAITS_HPP
9
10 #include <boost/histogram/fwd.hpp>
11 #include <tuple>
12 #include <type_traits>
13
14 namespace boost {
15
16 namespace accumulators {
17 template <class, class, class>
18 struct accumulator_set;
19 }
20
21 namespace histogram {
22 namespace detail {
23
24 template <bool WeightSupport, class... Ts>
25 struct accumulator_traits_holder {
26   using wsupport = std::integral_constant<bool, WeightSupport>;
27   using args = std::tuple<Ts...>;
28 };
29
30 template <class R, class T, class U, class... Ts>
31 accumulator_traits_holder<true, Ts...> accumulator_traits_impl_2(
32     R (T::*)(boost::histogram::weight_type<U>, Ts...));
33
34 template <class R, class T, class U, class... Ts>
35 accumulator_traits_holder<true, Ts...> accumulator_traits_impl_2(
36     R (T::*)(boost::histogram::weight_type<U>&&, Ts...));
37
38 template <class R, class T, class U, class... Ts>
39 accumulator_traits_holder<true, Ts...> accumulator_traits_impl_2(
40     R (T::*)(const boost::histogram::weight_type<U>&, Ts...));
41
42 template <class R, class T, class... Ts>
43 accumulator_traits_holder<false, Ts...> accumulator_traits_impl_2(R (T::*)(Ts...));
44
45 template <class T>
46 auto accumulator_traits_impl(T&)
47     -> decltype(std::declval<T&>() += 0, accumulator_traits_holder<true>{});
48
49 template <class T>
50 auto accumulator_traits_impl(T&) -> decltype(accumulator_traits_impl_2(&T::operator()));
51
52 // for boost.accumulators compatibility
53 template <class S, class F, class W>
54 accumulator_traits_holder<false, S> accumulator_traits_impl(
55     boost::accumulators::accumulator_set<S, F, W>&);
56
57 template <class T>
58 using accumulator_traits = decltype(accumulator_traits_impl(std::declval<T&>()));
59
60 } // namespace detail
61 } // namespace histogram
62 } // namespace boost
63
64 #endif