blob: 18bd7f435053f52dd8e9e62f9f73e8bc3d099e0a [file] [log] [blame]
Brad Bishop186aa672017-05-15 22:27:57 -04001#pragma once
2
3#include <tuple>
4#include <utility>
5
6namespace phosphor
7{
8namespace dbus
9{
10namespace monitoring
11{
12
13/** @brief A tuple of references. */
14template <typename... T>
15using TupleOfRefs = std::tuple<std::reference_wrapper<T>...>;
16
17namespace detail
18{
19/** @brief Less than implementation for tuples of references. */
Patrick Venture3d6d3182018-08-31 09:33:09 -070020template <size_t size, size_t i, typename T, typename U>
21struct TupleOfRefsLess
Brad Bishop186aa672017-05-15 22:27:57 -040022{
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 }
Brad Bishopd1eac882018-03-29 10:34:05 -040033 return TupleOfRefsLess<size, i + 1, T, U>::compare(l, r);
Brad Bishop186aa672017-05-15 22:27:57 -040034 }
35};
36
37/** @brief Less than specialization for tuple element sizeof...(tuple) +1. */
38template <size_t size, typename T, typename U>
39struct 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. */
49struct TupleOfRefsLess
50{
51 template <typename... T, typename... U>
Brad Bishopd1eac882018-03-29 10:34:05 -040052 constexpr bool operator()(const TupleOfRefs<T...>& l,
53 const TupleOfRefs<U...>& r) const
Brad Bishop186aa672017-05-15 22:27:57 -040054 {
55 static_assert(sizeof...(T) == sizeof...(U),
56 "Cannot compare tuples of different lengths.");
Brad Bishopd1eac882018-03-29 10:34:05 -040057 return detail::TupleOfRefsLess<sizeof...(T), 0, TupleOfRefs<T...>,
58 TupleOfRefs<U...>>::compare(l, r);
Brad Bishop186aa672017-05-15 22:27:57 -040059 }
60};
61
62} // namespace monitoring
63} // namespace dbus
64} // namespace phosphor