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