blob: 24ced13f52b6469ff7ea0e17fec404e2ba26e6bb [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(
Patrick Williams4ccd3962021-07-13 11:12:19 -050038 std::string("Invalid conversion in MakeVariantVisitor::") +
39 __PRETTY_FUNCTION__);
Brad Bishop9bbfcb12017-02-04 10:51:06 -050040 return T();
41 }
42 };
Brad Bishop65ffffa2016-11-29 12:31:31 -050043
Brad Bishop9bbfcb12017-02-04 10:51:06 -050044 /** @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>
Brad Bishop615b2a82018-03-29 10:32:41 -040050 struct Make<
51 T, Arg,
52 typename std::enable_if<std::is_convertible<Arg, T>::value>::type>
Brad Bishop9bbfcb12017-02-04 10:51:06 -050053 {
54 static auto make(Arg&& arg)
55 {
56 return T(std::forward<Arg>(arg));
57 }
58 };
59
60 /** @brief Make variant visitor. */
Patrick Venturea680d1e2018-10-14 13:34:26 -070061 template <typename Arg>
62 auto operator()(Arg&& arg) const
Brad Bishop9bbfcb12017-02-04 10:51:06 -050063 {
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 */
Patrick Venturea680d1e2018-10-14 13:34:26 -070076template <typename V, typename Arg>
77auto convertVariant(Arg&& v)
Brad Bishop9bbfcb12017-02-04 10:51:06 -050078{
Patrick Williams26f86682020-05-13 11:36:19 -050079 return std::visit(MakeVariantVisitor<V>(), v);
Brad Bishop9bbfcb12017-02-04 10:51:06 -050080}
Brad Bishop86521582017-02-15 01:10:15 -050081
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 */
Patrick Venturea680d1e2018-10-14 13:34:26 -070090template <typename Compare>
91struct CompareFirst
Brad Bishop86521582017-02-15 01:10:15 -050092{
93 /** @brief Construct a CompareFirst adapter.
94 *
95 * @param[in] c - The function object being adapted.
96 */
Brad Bishop615b2a82018-03-29 10:32:41 -040097 explicit CompareFirst(Compare&& c) : compare(std::forward<Compare>(c))
Brad Bishopa83db302020-12-06 14:51:23 -050098 {}
Brad Bishop86521582017-02-15 01:10:15 -050099
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>
Brad Bishop615b2a82018-03-29 10:32:41 -0400113 bool operator()(const std::pair<L1, L2>& l,
114 const std::pair<R1, R2>& r) const
Brad Bishop86521582017-02-15 01:10:15 -0500115 {
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. */
Patrick Venturea680d1e2018-10-14 13:34:26 -0700158template <typename Compare>
159CompareFirst<Compare> compareFirst(Compare&& c)
Brad Bishop86521582017-02-15 01:10:15 -0500160{
161 return CompareFirst<Compare>(std::forward<Compare>(c));
162}
163
164/** @struct RelPathCompare
165 * @brief Compare two strings after removing an optional prefix.
166 */
167struct RelPathCompare
168{
169 /** @brief Construct a RelPathCompare comparison functor.
170 *
171 * @param[in] p - The prefix to check for and remove.
172 */
Brad Bishop615b2a82018-03-29 10:32:41 -0400173 explicit RelPathCompare(const char* p) : prefix(p)
Brad Bishopa83db302020-12-06 14:51:23 -0500174 {}
Brad Bishop86521582017-02-15 01:10:15 -0500175
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};
Brad Bishop65ffffa2016-11-29 12:31:31 -0500205} // namespace manager
206} // namespace inventory
207} // namespace phosphor
208
209// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4