blob: eacc70e559d952a591d2df48d936e80b44d6121f [file] [log] [blame]
Brad Bishop65ffffa2016-11-29 12:31:31 -05001#pragma once
2
Brad Bishopd3d188d2018-12-11 16:49:29 -05003#include <sdbusplus/message/types.hpp>
Brad Bishopa83db302020-12-06 14:51:23 -05004
5#include <cstring>
Brad Bishopd3d188d2018-12-11 16:49:29 -05006#include <stdexcept>
7#include <string>
8#include <type_traits>
9#include <utility>
10
Brad Bishop65ffffa2016-11-29 12:31:31 -050011namespace phosphor
12{
13namespace inventory
14{
15namespace manager
16{
Brad Bishop9bbfcb12017-02-04 10:51:06 -050017/** @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 */
Patrick Venturea680d1e2018-10-14 13:34:26 -070022template <typename V>
23struct MakeVariantVisitor
Brad Bishop9bbfcb12017-02-04 10:51:06 -050024{
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 */
Patrick Venturea680d1e2018-10-14 13:34:26 -070032 template <typename T, typename Arg, typename Enable = void>
33 struct Make
Brad Bishop9bbfcb12017-02-04 10:51:06 -050034 {
35 static auto make(Arg&& arg)
36 {
William A. Kennington III6e94b652018-11-06 17:11:28 -080037 throw std::runtime_error(
38 "Invalid conversion in MakeVariantVisitor");
Brad Bishop9bbfcb12017-02-04 10:51:06 -050039 return T();
40 }
41 };
Brad Bishop65ffffa2016-11-29 12:31:31 -050042
Brad Bishop9bbfcb12017-02-04 10:51:06 -050043 /** @struct Make
44 * @brief Return variant visitor.
45 *
46 * struct Make specialization if Arg is in T (int -> variant<int, char>).
47 */
48 template <typename T, typename Arg>
Brad Bishop615b2a82018-03-29 10:32:41 -040049 struct Make<
50 T, Arg,
51 typename std::enable_if<std::is_convertible<Arg, T>::value>::type>
Brad Bishop9bbfcb12017-02-04 10:51:06 -050052 {
53 static auto make(Arg&& arg)
54 {
55 return T(std::forward<Arg>(arg));
56 }
57 };
58
59 /** @brief Make variant visitor. */
Patrick Venturea680d1e2018-10-14 13:34:26 -070060 template <typename Arg>
61 auto operator()(Arg&& arg) const
Brad Bishop9bbfcb12017-02-04 10:51:06 -050062 {
63 return Make<V, Arg>::make(arg);
64 }
65};
66
67/** @brief Convert variants with different contained types.
68 *
69 * @tparam V - The desired variant type.
70 * @tparam Arg - The source variant type.
71 *
72 * @param[in] v - The source variant.
73 * @returns - The converted variant.
74 */
Patrick Venturea680d1e2018-10-14 13:34:26 -070075template <typename V, typename Arg>
76auto convertVariant(Arg&& v)
Brad Bishop9bbfcb12017-02-04 10:51:06 -050077{
Patrick Williams26f86682020-05-13 11:36:19 -050078 return std::visit(MakeVariantVisitor<V>(), v);
Brad Bishop9bbfcb12017-02-04 10:51:06 -050079}
Brad Bishop86521582017-02-15 01:10:15 -050080
81/** @struct CompareFirst
82 * @brief std::pair binary comparison adapter.
83 *
84 * Adapt a binary comparison function to a comparison of
85 * the first pair element.
86 *
87 * @tparam Compare - The function object type being adapted.
88 */
Patrick Venturea680d1e2018-10-14 13:34:26 -070089template <typename Compare>
90struct CompareFirst
Brad Bishop86521582017-02-15 01:10:15 -050091{
92 /** @brief Construct a CompareFirst adapter.
93 *
94 * @param[in] c - The function object being adapted.
95 */
Brad Bishop615b2a82018-03-29 10:32:41 -040096 explicit CompareFirst(Compare&& c) : compare(std::forward<Compare>(c))
Brad Bishopa83db302020-12-06 14:51:23 -050097 {}
Brad Bishop86521582017-02-15 01:10:15 -050098
99 /** @brief Compare two pairs adapter.
100 *
101 * @tparam L1 - First pair first_type.
102 * @tparam L2 - First pair second_type.
103 * @tparam R1 - Second pair first_type, convertible to L1.
104 * @tparam R2 - Second pair second_type.
105 *
106 * @param[in] l - The first pair.
107 * @param[in] r - The second pair.
108 *
109 * @returns - The result of the comparison.
110 */
111 template <typename L1, typename L2, typename R1, typename R2>
Brad Bishop615b2a82018-03-29 10:32:41 -0400112 bool operator()(const std::pair<L1, L2>& l,
113 const std::pair<R1, R2>& r) const
Brad Bishop86521582017-02-15 01:10:15 -0500114 {
115 return compare(l.first, r.first);
116 }
117
118 /** @brief Compare one pair adapter.
119 *
120 * @tparam L1 - Pair first_type.
121 * @tparam L2 - Pair second_type.
122 * @tparam R - Convertible to L1 for comparison.
123 *
124 * @param[in] l - The pair.
125 * @param[in] r - To be compared to l.first.
126 *
127 * @returns - The result of the comparison.
128 */
129 template <typename L1, typename L2, typename R>
130 bool operator()(const std::pair<L1, L2>& l, const R& r) const
131 {
132 return compare(l.first, r);
133 }
134
135 /** @brief Compare one pair adapter.
136 *
137 * @tparam L - Convertible to R1 for comparison.
138 * @tparam R1 - Pair first_type.
139 * @tparam R2 - Pair second_type.
140 *
141 * @param[in] l - To be compared to r.first.
142 * @param[in] r - The pair.
143 *
144 * @returns - The result of the comparison.
145 */
146 template <typename L, typename R1, typename R2>
147 bool operator()(const L& l, const std::pair<R1, R2>& r) const
148 {
149 return compare(l, r.first);
150 }
151
152 /* @brief The function being adapted. */
153 Compare compare;
154};
155
156/* @brief Implicit template instantation wrapper for CompareFirst. */
Patrick Venturea680d1e2018-10-14 13:34:26 -0700157template <typename Compare>
158CompareFirst<Compare> compareFirst(Compare&& c)
Brad Bishop86521582017-02-15 01:10:15 -0500159{
160 return CompareFirst<Compare>(std::forward<Compare>(c));
161}
162
163/** @struct RelPathCompare
164 * @brief Compare two strings after removing an optional prefix.
165 */
166struct RelPathCompare
167{
168 /** @brief Construct a RelPathCompare comparison functor.
169 *
170 * @param[in] p - The prefix to check for and remove.
171 */
Brad Bishop615b2a82018-03-29 10:32:41 -0400172 explicit RelPathCompare(const char* p) : prefix(p)
Brad Bishopa83db302020-12-06 14:51:23 -0500173 {}
Brad Bishop86521582017-02-15 01:10:15 -0500174
175 /** @brief Check for the prefix and remove if found.
176 *
177 * @param[in] s - The string to check for and remove prefix from.
178 */
179 auto relPath(const std::string& s) const
180 {
181 if (s.find(prefix) == 0)
182 {
183 return s.substr(strlen(prefix));
184 }
185
186 return s;
187 }
188
189 /** @brief Comparison method.
190 *
191 * @param[in] l - The first string.
192 * @param[in] r - The second string.
193 *
194 * @returns - The result of the comparison.
195 */
196 bool operator()(const std::string& l, const std::string& r) const
197 {
198 return relPath(l) < relPath(r);
199 }
200
201 /* The path prefix to remove when comparing two paths. */
202 const char* prefix;
203};
Brad Bishop65ffffa2016-11-29 12:31:31 -0500204} // namespace manager
205} // namespace inventory
206} // namespace phosphor
207
208// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4