1 #pragma once 2 3 #include <sdbusplus/message/types.hpp> 4 5 #include <cstring> 6 #include <stdexcept> 7 #include <string> 8 #include <type_traits> 9 #include <utility> 10 11 namespace phosphor 12 { 13 namespace inventory 14 { 15 namespace manager 16 { 17 /** @struct MakeVariantVisitor 18 * @brief Return a variant if the visited type is a possible variant type. 19 * 20 * @tparam V - The desired variant type. 21 */ 22 template <typename V> 23 struct MakeVariantVisitor 24 { 25 /** @struct Make 26 * @brief Return variant visitor. 27 * 28 * @tparam T - The variant type to return. 29 * @tparam Arg - The type being visited in the source variant. 30 * @tparam Enable - Overload resolution removal. 31 */ 32 template <typename T, typename Arg, typename Enable = void> 33 struct Make 34 { 35 static auto make(Arg&& arg) 36 { 37 throw std::runtime_error( 38 std::string("Invalid conversion in MakeVariantVisitor::") + 39 __PRETTY_FUNCTION__); 40 return T(); 41 } 42 }; 43 44 /** @struct Make 45 * @brief Return variant visitor. 46 * 47 * struct Make specialization if Arg is in T (int -> variant<int, char>). 48 */ 49 template <typename T, typename Arg> 50 struct Make< 51 T, Arg, 52 typename std::enable_if<std::is_convertible<Arg, T>::value>::type> 53 { 54 static auto make(Arg&& arg) 55 { 56 return T(std::forward<Arg>(arg)); 57 } 58 }; 59 60 /** @brief Make variant visitor. */ 61 template <typename Arg> 62 auto operator()(Arg&& arg) const 63 { 64 return Make<V, Arg>::make(arg); 65 } 66 }; 67 68 /** @brief Convert variants with different contained types. 69 * 70 * @tparam V - The desired variant type. 71 * @tparam Arg - The source variant type. 72 * 73 * @param[in] v - The source variant. 74 * @returns - The converted variant. 75 */ 76 template <typename V, typename Arg> 77 auto convertVariant(Arg&& v) 78 { 79 return std::visit(MakeVariantVisitor<V>(), v); 80 } 81 82 /** @struct CompareFirst 83 * @brief std::pair binary comparison adapter. 84 * 85 * Adapt a binary comparison function to a comparison of 86 * the first pair element. 87 * 88 * @tparam Compare - The function object type being adapted. 89 */ 90 template <typename Compare> 91 struct CompareFirst 92 { 93 /** @brief Construct a CompareFirst adapter. 94 * 95 * @param[in] c - The function object being adapted. 96 */ 97 explicit CompareFirst(Compare&& c) : compare(std::forward<Compare>(c)) 98 {} 99 100 /** @brief Compare two pairs adapter. 101 * 102 * @tparam L1 - First pair first_type. 103 * @tparam L2 - First pair second_type. 104 * @tparam R1 - Second pair first_type, convertible to L1. 105 * @tparam R2 - Second pair second_type. 106 * 107 * @param[in] l - The first pair. 108 * @param[in] r - The second pair. 109 * 110 * @returns - The result of the comparison. 111 */ 112 template <typename L1, typename L2, typename R1, typename R2> 113 bool operator()(const std::pair<L1, L2>& l, 114 const std::pair<R1, R2>& r) const 115 { 116 return compare(l.first, r.first); 117 } 118 119 /** @brief Compare one pair adapter. 120 * 121 * @tparam L1 - Pair first_type. 122 * @tparam L2 - Pair second_type. 123 * @tparam R - Convertible to L1 for comparison. 124 * 125 * @param[in] l - The pair. 126 * @param[in] r - To be compared to l.first. 127 * 128 * @returns - The result of the comparison. 129 */ 130 template <typename L1, typename L2, typename R> 131 bool operator()(const std::pair<L1, L2>& l, const R& r) const 132 { 133 return compare(l.first, r); 134 } 135 136 /** @brief Compare one pair adapter. 137 * 138 * @tparam L - Convertible to R1 for comparison. 139 * @tparam R1 - Pair first_type. 140 * @tparam R2 - Pair second_type. 141 * 142 * @param[in] l - To be compared to r.first. 143 * @param[in] r - The pair. 144 * 145 * @returns - The result of the comparison. 146 */ 147 template <typename L, typename R1, typename R2> 148 bool operator()(const L& l, const std::pair<R1, R2>& r) const 149 { 150 return compare(l, r.first); 151 } 152 153 /* @brief The function being adapted. */ 154 Compare compare; 155 }; 156 157 /* @brief Implicit template instantation wrapper for CompareFirst. */ 158 template <typename Compare> 159 CompareFirst<Compare> compareFirst(Compare&& c) 160 { 161 return CompareFirst<Compare>(std::forward<Compare>(c)); 162 } 163 164 /** @struct RelPathCompare 165 * @brief Compare two strings after removing an optional prefix. 166 */ 167 struct RelPathCompare 168 { 169 /** @brief Construct a RelPathCompare comparison functor. 170 * 171 * @param[in] p - The prefix to check for and remove. 172 */ 173 explicit RelPathCompare(const char* p) : prefix(p) 174 {} 175 176 /** @brief Check for the prefix and remove if found. 177 * 178 * @param[in] s - The string to check for and remove prefix from. 179 */ 180 auto relPath(const std::string& s) const 181 { 182 if (s.find(prefix) == 0) 183 { 184 return s.substr(strlen(prefix)); 185 } 186 187 return s; 188 } 189 190 /** @brief Comparison method. 191 * 192 * @param[in] l - The first string. 193 * @param[in] r - The second string. 194 * 195 * @returns - The result of the comparison. 196 */ 197 bool operator()(const std::string& l, const std::string& r) const 198 { 199 return relPath(l) < relPath(r); 200 } 201 202 /* The path prefix to remove when comparing two paths. */ 203 const char* prefix; 204 }; 205 } // namespace manager 206 } // namespace inventory 207 } // namespace phosphor 208 209 // vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 210