blob: aacee5e77ef8bad04d1d887b6455a6346b5d91a1 [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 {
29 throw sdbusplus::message::variant_ns::bad_variant_access(
30 "in MakeVariantVisitor");
31 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{
70 return sdbusplus::message::variant_ns::apply_visitor(
Brad Bishop615b2a82018-03-29 10:32:41 -040071 MakeVariantVisitor<V>(), v);
Brad Bishop9bbfcb12017-02-04 10:51:06 -050072}
Brad Bishop86521582017-02-15 01:10:15 -050073
74/** @struct CompareFirst
75 * @brief std::pair binary comparison adapter.
76 *
77 * Adapt a binary comparison function to a comparison of
78 * the first pair element.
79 *
80 * @tparam Compare - The function object type being adapted.
81 */
Patrick Venturea680d1e2018-10-14 13:34:26 -070082template <typename Compare>
83struct CompareFirst
Brad Bishop86521582017-02-15 01:10:15 -050084{
85 /** @brief Construct a CompareFirst adapter.
86 *
87 * @param[in] c - The function object being adapted.
88 */
Brad Bishop615b2a82018-03-29 10:32:41 -040089 explicit CompareFirst(Compare&& c) : compare(std::forward<Compare>(c))
90 {
91 }
Brad Bishop86521582017-02-15 01:10:15 -050092
93 /** @brief Compare two pairs adapter.
94 *
95 * @tparam L1 - First pair first_type.
96 * @tparam L2 - First pair second_type.
97 * @tparam R1 - Second pair first_type, convertible to L1.
98 * @tparam R2 - Second pair second_type.
99 *
100 * @param[in] l - The first pair.
101 * @param[in] r - The second pair.
102 *
103 * @returns - The result of the comparison.
104 */
105 template <typename L1, typename L2, typename R1, typename R2>
Brad Bishop615b2a82018-03-29 10:32:41 -0400106 bool operator()(const std::pair<L1, L2>& l,
107 const std::pair<R1, R2>& r) const
Brad Bishop86521582017-02-15 01:10:15 -0500108 {
109 return compare(l.first, r.first);
110 }
111
112 /** @brief Compare one pair adapter.
113 *
114 * @tparam L1 - Pair first_type.
115 * @tparam L2 - Pair second_type.
116 * @tparam R - Convertible to L1 for comparison.
117 *
118 * @param[in] l - The pair.
119 * @param[in] r - To be compared to l.first.
120 *
121 * @returns - The result of the comparison.
122 */
123 template <typename L1, typename L2, typename R>
124 bool operator()(const std::pair<L1, L2>& l, const R& r) const
125 {
126 return compare(l.first, r);
127 }
128
129 /** @brief Compare one pair adapter.
130 *
131 * @tparam L - Convertible to R1 for comparison.
132 * @tparam R1 - Pair first_type.
133 * @tparam R2 - Pair second_type.
134 *
135 * @param[in] l - To be compared to r.first.
136 * @param[in] r - The pair.
137 *
138 * @returns - The result of the comparison.
139 */
140 template <typename L, typename R1, typename R2>
141 bool operator()(const L& l, const std::pair<R1, R2>& r) const
142 {
143 return compare(l, r.first);
144 }
145
146 /* @brief The function being adapted. */
147 Compare compare;
148};
149
150/* @brief Implicit template instantation wrapper for CompareFirst. */
Patrick Venturea680d1e2018-10-14 13:34:26 -0700151template <typename Compare>
152CompareFirst<Compare> compareFirst(Compare&& c)
Brad Bishop86521582017-02-15 01:10:15 -0500153{
154 return CompareFirst<Compare>(std::forward<Compare>(c));
155}
156
157/** @struct RelPathCompare
158 * @brief Compare two strings after removing an optional prefix.
159 */
160struct RelPathCompare
161{
162 /** @brief Construct a RelPathCompare comparison functor.
163 *
164 * @param[in] p - The prefix to check for and remove.
165 */
Brad Bishop615b2a82018-03-29 10:32:41 -0400166 explicit RelPathCompare(const char* p) : prefix(p)
167 {
168 }
Brad Bishop86521582017-02-15 01:10:15 -0500169
170 /** @brief Check for the prefix and remove if found.
171 *
172 * @param[in] s - The string to check for and remove prefix from.
173 */
174 auto relPath(const std::string& s) const
175 {
176 if (s.find(prefix) == 0)
177 {
178 return s.substr(strlen(prefix));
179 }
180
181 return s;
182 }
183
184 /** @brief Comparison method.
185 *
186 * @param[in] l - The first string.
187 * @param[in] r - The second string.
188 *
189 * @returns - The result of the comparison.
190 */
191 bool operator()(const std::string& l, const std::string& r) const
192 {
193 return relPath(l) < relPath(r);
194 }
195
196 /* The path prefix to remove when comparing two paths. */
197 const char* prefix;
198};
Brad Bishop65ffffa2016-11-29 12:31:31 -0500199} // namespace manager
200} // namespace inventory
201} // namespace phosphor
202
203// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4