blob: 3e896be4a1657955c9c5babe78c419499ae0e3d9 [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. */
Brad Bishopd1eac882018-03-29 10:34:05 -040020template <size_t size, size_t i, typename T, typename U> struct TupleOfRefsLess
Brad Bishop186aa672017-05-15 22:27:57 -040021{
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 }
Brad Bishopd1eac882018-03-29 10:34:05 -040032 return TupleOfRefsLess<size, i + 1, T, U>::compare(l, r);
Brad Bishop186aa672017-05-15 22:27:57 -040033 }
34};
35
36/** @brief Less than specialization for tuple element sizeof...(tuple) +1. */
37template <size_t size, typename T, typename U>
38struct 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. */
48struct TupleOfRefsLess
49{
50 template <typename... T, typename... U>
Brad Bishopd1eac882018-03-29 10:34:05 -040051 constexpr bool operator()(const TupleOfRefs<T...>& l,
52 const TupleOfRefs<U...>& r) const
Brad Bishop186aa672017-05-15 22:27:57 -040053 {
54 static_assert(sizeof...(T) == sizeof...(U),
55 "Cannot compare tuples of different lengths.");
Brad Bishopd1eac882018-03-29 10:34:05 -040056 return detail::TupleOfRefsLess<sizeof...(T), 0, TupleOfRefs<T...>,
57 TupleOfRefs<U...>>::compare(l, r);
Brad Bishop186aa672017-05-15 22:27:57 -040058 }
59};
60
61} // namespace monitoring
62} // namespace dbus
63} // namespace phosphor