1 #pragma once
2 
3 #include <cstddef>
4 #include <tuple>
5 #include <utility>
6 
7 namespace phosphor
8 {
9 namespace dbus
10 {
11 namespace monitoring
12 {
13 
14 /** @brief A tuple of references. */
15 template <typename... T>
16 using TupleOfRefs = std::tuple<std::reference_wrapper<T>...>;
17 
18 namespace detail
19 {
20 /** @brief Less than implementation for tuples of references. */
21 template <size_t size, size_t i, typename T, typename U>
22 struct TupleOfRefsLess
23 {
comparephosphor::dbus::monitoring::detail::TupleOfRefsLess24     static constexpr bool compare(const T& l, const U& r)
25     {
26         if (std::get<i>(l).get() < std::get<i>(r).get())
27         {
28             return true;
29         }
30         if (std::get<i>(r).get() < std::get<i>(l).get())
31         {
32             return false;
33         }
34         return TupleOfRefsLess<size, i + 1, T, U>::compare(l, r);
35     }
36 };
37 
38 /** @brief Less than specialization for tuple element sizeof...(tuple) +1. */
39 template <size_t size, typename T, typename U>
40 struct TupleOfRefsLess<size, size, T, U>
41 {
comparephosphor::dbus::monitoring::detail::TupleOfRefsLess42     static constexpr bool compare(const T& /* l */, const U& /* r */)
43     {
44         return false;
45     }
46 };
47 } // namespace detail
48 
49 /** @brief Less than comparison for tuples of references. */
50 struct TupleOfRefsLess
51 {
52     template <typename... T, typename... U>
operator ()phosphor::dbus::monitoring::TupleOfRefsLess53     constexpr bool operator()(const TupleOfRefs<T...>& l,
54                               const TupleOfRefs<U...>& r) const
55     {
56         static_assert(sizeof...(T) == sizeof...(U),
57                       "Cannot compare tuples of different lengths.");
58         return detail::TupleOfRefsLess<sizeof...(T), 0, TupleOfRefs<T...>,
59                                        TupleOfRefs<U...>>::compare(l, r);
60     }
61 };
62 
63 } // namespace monitoring
64 } // namespace dbus
65 } // namespace phosphor
66