]>
Commit | Line | Data |
---|---|---|
92f5a8d4 TL |
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 | ||
f67539c2 | 10 | #include <boost/histogram/detail/priority.hpp> |
92f5a8d4 TL |
11 | #include <boost/histogram/fwd.hpp> |
12 | #include <tuple> | |
13 | #include <type_traits> | |
14 | ||
15 | namespace boost { | |
16 | ||
f67539c2 | 17 | // forward declare accumulator_set so that it can be matched below |
92f5a8d4 TL |
18 | namespace accumulators { |
19 | template <class, class, class> | |
20 | struct accumulator_set; | |
21 | } | |
22 | ||
23 | namespace histogram { | |
24 | namespace detail { | |
25 | ||
26 | template <bool WeightSupport, class... Ts> | |
27 | struct accumulator_traits_holder { | |
f67539c2 | 28 | static constexpr bool weight_support = WeightSupport; |
92f5a8d4 TL |
29 | using args = std::tuple<Ts...>; |
30 | }; | |
31 | ||
f67539c2 | 32 | // member function pointer with weight_type as first argument is better match |
92f5a8d4 | 33 | template <class R, class T, class U, class... Ts> |
f67539c2 | 34 | accumulator_traits_holder<true, Ts...> accumulator_traits_impl_call_op( |
92f5a8d4 TL |
35 | R (T::*)(boost::histogram::weight_type<U>, Ts...)); |
36 | ||
37 | template <class R, class T, class U, class... Ts> | |
f67539c2 TL |
38 | accumulator_traits_holder<true, Ts...> accumulator_traits_impl_call_op( |
39 | R (T::*)(boost::histogram::weight_type<U>&, Ts...)); | |
40 | ||
41 | template <class R, class T, class U, class... Ts> | |
42 | accumulator_traits_holder<true, Ts...> accumulator_traits_impl_call_op( | |
92f5a8d4 TL |
43 | R (T::*)(boost::histogram::weight_type<U>&&, Ts...)); |
44 | ||
45 | template <class R, class T, class U, class... Ts> | |
f67539c2 | 46 | accumulator_traits_holder<true, Ts...> accumulator_traits_impl_call_op( |
92f5a8d4 TL |
47 | R (T::*)(const boost::histogram::weight_type<U>&, Ts...)); |
48 | ||
f67539c2 | 49 | // member function pointer only considered if all specializations above fail |
92f5a8d4 | 50 | template <class R, class T, class... Ts> |
f67539c2 | 51 | accumulator_traits_holder<false, Ts...> accumulator_traits_impl_call_op(R (T::*)(Ts...)); |
92f5a8d4 TL |
52 | |
53 | template <class T> | |
1e59de90 | 54 | auto accumulator_traits_impl(T&, priority<2>) |
f67539c2 TL |
55 | -> decltype(accumulator_traits_impl_call_op(&T::operator())); |
56 | ||
1e59de90 TL |
57 | template <class T> |
58 | auto accumulator_traits_impl(T&, priority<2>) | |
59 | -> decltype(std::declval<T&>() += std::declval<boost::histogram::weight_type<int>>(), | |
60 | accumulator_traits_holder<true>{}); | |
61 | ||
62 | // fallback for simple arithmetic types that do not implement adding a weight_type | |
f67539c2 TL |
63 | template <class T> |
64 | auto accumulator_traits_impl(T&, priority<1>) | |
92f5a8d4 TL |
65 | -> decltype(std::declval<T&>() += 0, accumulator_traits_holder<true>{}); |
66 | ||
67 | template <class T> | |
f67539c2 | 68 | auto accumulator_traits_impl(T&, priority<0>) -> accumulator_traits_holder<false>; |
92f5a8d4 TL |
69 | |
70 | // for boost.accumulators compatibility | |
71 | template <class S, class F, class W> | |
72 | accumulator_traits_holder<false, S> accumulator_traits_impl( | |
1e59de90 | 73 | boost::accumulators::accumulator_set<S, F, W>&, priority<2>) { |
f67539c2 TL |
74 | static_assert(std::is_same<W, void>::value, |
75 | "accumulator_set with weights is not directly supported, please use " | |
76 | "a wrapper class that implements the Accumulator concept"); | |
77 | } | |
92f5a8d4 TL |
78 | |
79 | template <class T> | |
f67539c2 | 80 | using accumulator_traits = |
1e59de90 | 81 | decltype(accumulator_traits_impl(std::declval<T&>(), priority<2>{})); |
92f5a8d4 TL |
82 | |
83 | } // namespace detail | |
84 | } // namespace histogram | |
85 | } // namespace boost | |
86 | ||
87 | #endif |