xref: /openbmc/phosphor-dbus-monitor/src/tupleref.hpp (revision 3d6d3182ee0b0e88b81fbbbe5c91dea3e99425a9)
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>
21 struct TupleOfRefsLess
22 {
23     static constexpr bool compare(const T& l, const U& r)
24     {
25         if (std::get<i>(l).get() < std::get<i>(r).get())
26         {
27             return true;
28         }
29         if (std::get<i>(r).get() < std::get<i>(l).get())
30         {
31             return false;
32         }
33         return TupleOfRefsLess<size, i + 1, T, U>::compare(l, r);
34     }
35 };
36 
37 /** @brief Less than specialization for tuple element sizeof...(tuple) +1. */
38 template <size_t size, typename T, typename U>
39 struct TupleOfRefsLess<size, size, T, U>
40 {
41     static constexpr bool compare(const T& l, const U& r)
42     {
43         return false;
44     }
45 };
46 } // namespace detail
47 
48 /** @brief Less than comparison for tuples of references. */
49 struct TupleOfRefsLess
50 {
51     template <typename... T, typename... U>
52     constexpr bool operator()(const TupleOfRefs<T...>& l,
53                               const TupleOfRefs<U...>& r) const
54     {
55         static_assert(sizeof...(T) == sizeof...(U),
56                       "Cannot compare tuples of different lengths.");
57         return detail::TupleOfRefsLess<sizeof...(T), 0, TupleOfRefs<T...>,
58                                        TupleOfRefs<U...>>::compare(l, r);
59     }
60 };
61 
62 } // namespace monitoring
63 } // namespace dbus
64 } // namespace phosphor
65