blob: 2fd0805d7179b5a2d5b875212423dcf488252ef4 [file] [log] [blame]
Brad Bishop65ffffa2016-11-29 12:31:31 -05001#pragma once
2
3namespace phosphor
4{
5namespace inventory
6{
7namespace manager
8{
Brad Bishop9bbfcb12017-02-04 10:51:06 -05009/** @struct MakeVariantVisitor
10 * @brief Return a variant if the visited type is a possible variant type.
11 *
12 * @tparam V - The desired variant type.
13 */
Patrick Venturea680d1e2018-10-14 13:34:26 -070014template <typename V>
15struct MakeVariantVisitor
Brad Bishop9bbfcb12017-02-04 10:51:06 -050016{
17 /** @struct Make
18 * @brief Return variant visitor.
19 *
20 * @tparam T - The variant type to return.
21 * @tparam Arg - The type being visited in the source variant.
22 * @tparam Enable - Overload resolution removal.
23 */
Patrick Venturea680d1e2018-10-14 13:34:26 -070024 template <typename T, typename Arg, typename Enable = void>
25 struct Make
Brad Bishop9bbfcb12017-02-04 10:51:06 -050026 {
27 static auto make(Arg&& arg)
28 {
William A. Kennington III6e94b652018-11-06 17:11:28 -080029 throw std::runtime_error(
30 "Invalid conversion in MakeVariantVisitor");
Brad Bishop9bbfcb12017-02-04 10:51:06 -050031 return T();
32 }
33 };
Brad Bishop65ffffa2016-11-29 12:31:31 -050034
Brad Bishop9bbfcb12017-02-04 10:51:06 -050035 /** @struct Make
36 * @brief Return variant visitor.
37 *
38 * struct Make specialization if Arg is in T (int -> variant<int, char>).
39 */
40 template <typename T, typename Arg>
Brad Bishop615b2a82018-03-29 10:32:41 -040041 struct Make<
42 T, Arg,
43 typename std::enable_if<std::is_convertible<Arg, T>::value>::type>
Brad Bishop9bbfcb12017-02-04 10:51:06 -050044 {
45 static auto make(Arg&& arg)
46 {
47 return T(std::forward<Arg>(arg));
48 }
49 };
50
51 /** @brief Make variant visitor. */
Patrick Venturea680d1e2018-10-14 13:34:26 -070052 template <typename Arg>
53 auto operator()(Arg&& arg) const
Brad Bishop9bbfcb12017-02-04 10:51:06 -050054 {
55 return Make<V, Arg>::make(arg);
56 }
57};
58
59/** @brief Convert variants with different contained types.
60 *
61 * @tparam V - The desired variant type.
62 * @tparam Arg - The source variant type.
63 *
64 * @param[in] v - The source variant.
65 * @returns - The converted variant.
66 */
Patrick Venturea680d1e2018-10-14 13:34:26 -070067template <typename V, typename Arg>
68auto convertVariant(Arg&& v)
Brad Bishop9bbfcb12017-02-04 10:51:06 -050069{
William A. Kennington III6e94b652018-11-06 17:11:28 -080070 return sdbusplus::message::variant_ns::visit(MakeVariantVisitor<V>(), v);
Brad Bishop9bbfcb12017-02-04 10:51:06 -050071}
Brad Bishop86521582017-02-15 01:10:15 -050072
73/** @struct CompareFirst
74 * @brief std::pair binary comparison adapter.
75 *
76 * Adapt a binary comparison function to a comparison of
77 * the first pair element.
78 *
79 * @tparam Compare - The function object type being adapted.
80 */
Patrick Venturea680d1e2018-10-14 13:34:26 -070081template <typename Compare>
82struct CompareFirst
Brad Bishop86521582017-02-15 01:10:15 -050083{
84 /** @brief Construct a CompareFirst adapter.
85 *
86 * @param[in] c - The function object being adapted.
87 */
Brad Bishop615b2a82018-03-29 10:32:41 -040088 explicit CompareFirst(Compare&& c) : compare(std::forward<Compare>(c))
89 {
90 }
Brad Bishop86521582017-02-15 01:10:15 -050091
92 /** @brief Compare two pairs adapter.
93 *
94 * @tparam L1 - First pair first_type.
95 * @tparam L2 - First pair second_type.
96 * @tparam R1 - Second pair first_type, convertible to L1.
97 * @tparam R2 - Second pair second_type.
98 *
99 * @param[in] l - The first pair.
100 * @param[in] r - The second pair.
101 *
102 * @returns - The result of the comparison.
103 */
104 template <typename L1, typename L2, typename R1, typename R2>
Brad Bishop615b2a82018-03-29 10:32:41 -0400105 bool operator()(const std::pair<L1, L2>& l,
106 const std::pair<R1, R2>& r) const
Brad Bishop86521582017-02-15 01:10:15 -0500107 {
108 return compare(l.first, r.first);
109 }
110
111 /** @brief Compare one pair adapter.
112 *
113 * @tparam L1 - Pair first_type.
114 * @tparam L2 - Pair second_type.
115 * @tparam R - Convertible to L1 for comparison.
116 *
117 * @param[in] l - The pair.
118 * @param[in] r - To be compared to l.first.
119 *
120 * @returns - The result of the comparison.
121 */
122 template <typename L1, typename L2, typename R>
123 bool operator()(const std::pair<L1, L2>& l, const R& r) const
124 {
125 return compare(l.first, r);
126 }
127
128 /** @brief Compare one pair adapter.
129 *
130 * @tparam L - Convertible to R1 for comparison.
131 * @tparam R1 - Pair first_type.
132 * @tparam R2 - Pair second_type.
133 *
134 * @param[in] l - To be compared to r.first.
135 * @param[in] r - The pair.
136 *
137 * @returns - The result of the comparison.
138 */
139 template <typename L, typename R1, typename R2>
140 bool operator()(const L& l, const std::pair<R1, R2>& r) const
141 {
142 return compare(l, r.first);
143 }
144
145 /* @brief The function being adapted. */
146 Compare compare;
147};
148
149/* @brief Implicit template instantation wrapper for CompareFirst. */
Patrick Venturea680d1e2018-10-14 13:34:26 -0700150template <typename Compare>
151CompareFirst<Compare> compareFirst(Compare&& c)
Brad Bishop86521582017-02-15 01:10:15 -0500152{
153 return CompareFirst<Compare>(std::forward<Compare>(c));
154}
155
156/** @struct RelPathCompare
157 * @brief Compare two strings after removing an optional prefix.
158 */
159struct RelPathCompare
160{
161 /** @brief Construct a RelPathCompare comparison functor.
162 *
163 * @param[in] p - The prefix to check for and remove.
164 */
Brad Bishop615b2a82018-03-29 10:32:41 -0400165 explicit RelPathCompare(const char* p) : prefix(p)
166 {
167 }
Brad Bishop86521582017-02-15 01:10:15 -0500168
169 /** @brief Check for the prefix and remove if found.
170 *
171 * @param[in] s - The string to check for and remove prefix from.
172 */
173 auto relPath(const std::string& s) const
174 {
175 if (s.find(prefix) == 0)
176 {
177 return s.substr(strlen(prefix));
178 }
179
180 return s;
181 }
182
183 /** @brief Comparison method.
184 *
185 * @param[in] l - The first string.
186 * @param[in] r - The second string.
187 *
188 * @returns - The result of the comparison.
189 */
190 bool operator()(const std::string& l, const std::string& r) const
191 {
192 return relPath(l) < relPath(r);
193 }
194
195 /* The path prefix to remove when comparing two paths. */
196 const char* prefix;
197};
Brad Bishop65ffffa2016-11-29 12:31:31 -0500198} // namespace manager
199} // namespace inventory
200} // namespace phosphor
201
202// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4