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