blob: 2db1d378687c2359c9efda8be124d70f819209eb [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 */
14template <typename V>
15struct MakeVariantVisitor
16{
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 */
24 template <typename T, typename Arg, typename Enable = void>
25 struct Make
26 {
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>
41 struct Make<T, Arg,
42 typename std::enable_if<std::is_convertible<Arg, T>::value>::type>
43 {
44 static auto make(Arg&& arg)
45 {
46 return T(std::forward<Arg>(arg));
47 }
48 };
49
50 /** @brief Make variant visitor. */
51 template <typename Arg>
52 auto operator()(Arg&& arg) const
53 {
54 return Make<V, Arg>::make(arg);
55 }
56};
57
58/** @brief Convert variants with different contained types.
59 *
60 * @tparam V - The desired variant type.
61 * @tparam Arg - The source variant type.
62 *
63 * @param[in] v - The source variant.
64 * @returns - The converted variant.
65 */
66template <typename V, typename Arg>
67auto convertVariant(Arg&& v)
68{
69 return sdbusplus::message::variant_ns::apply_visitor(
70 MakeVariantVisitor<V>(), v);
71}
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 */
81template <typename Compare>
82struct CompareFirst
83{
84 /** @brief Construct a CompareFirst adapter.
85 *
86 * @param[in] c - The function object being adapted.
87 */
88 explicit CompareFirst(Compare&& c) : compare(std::forward<Compare>(c)) {}
89
90 /** @brief Compare two pairs adapter.
91 *
92 * @tparam L1 - First pair first_type.
93 * @tparam L2 - First pair second_type.
94 * @tparam R1 - Second pair first_type, convertible to L1.
95 * @tparam R2 - Second pair second_type.
96 *
97 * @param[in] l - The first pair.
98 * @param[in] r - The second pair.
99 *
100 * @returns - The result of the comparison.
101 */
102 template <typename L1, typename L2, typename R1, typename R2>
103 bool operator()(const std::pair<L1, L2>& l, const std::pair<R1, R2>& r) const
104 {
105 return compare(l.first, r.first);
106 }
107
108 /** @brief Compare one pair adapter.
109 *
110 * @tparam L1 - Pair first_type.
111 * @tparam L2 - Pair second_type.
112 * @tparam R - Convertible to L1 for comparison.
113 *
114 * @param[in] l - The pair.
115 * @param[in] r - To be compared to l.first.
116 *
117 * @returns - The result of the comparison.
118 */
119 template <typename L1, typename L2, typename R>
120 bool operator()(const std::pair<L1, L2>& l, const R& r) const
121 {
122 return compare(l.first, r);
123 }
124
125 /** @brief Compare one pair adapter.
126 *
127 * @tparam L - Convertible to R1 for comparison.
128 * @tparam R1 - Pair first_type.
129 * @tparam R2 - Pair second_type.
130 *
131 * @param[in] l - To be compared to r.first.
132 * @param[in] r - The pair.
133 *
134 * @returns - The result of the comparison.
135 */
136 template <typename L, typename R1, typename R2>
137 bool operator()(const L& l, const std::pair<R1, R2>& r) const
138 {
139 return compare(l, r.first);
140 }
141
142 /* @brief The function being adapted. */
143 Compare compare;
144};
145
146/* @brief Implicit template instantation wrapper for CompareFirst. */
147template <typename Compare>
148CompareFirst<Compare> compareFirst(Compare&& c)
149{
150 return CompareFirst<Compare>(std::forward<Compare>(c));
151}
152
153/** @struct RelPathCompare
154 * @brief Compare two strings after removing an optional prefix.
155 */
156struct RelPathCompare
157{
158 /** @brief Construct a RelPathCompare comparison functor.
159 *
160 * @param[in] p - The prefix to check for and remove.
161 */
162 explicit RelPathCompare(const char* p) : prefix(p) {}
163
164 /** @brief Check for the prefix and remove if found.
165 *
166 * @param[in] s - The string to check for and remove prefix from.
167 */
168 auto relPath(const std::string& s) const
169 {
170 if (s.find(prefix) == 0)
171 {
172 return s.substr(strlen(prefix));
173 }
174
175 return s;
176 }
177
178 /** @brief Comparison method.
179 *
180 * @param[in] l - The first string.
181 * @param[in] r - The second string.
182 *
183 * @returns - The result of the comparison.
184 */
185 bool operator()(const std::string& l, const std::string& r) const
186 {
187 return relPath(l) < relPath(r);
188 }
189
190 /* The path prefix to remove when comparing two paths. */
191 const char* prefix;
192};
Brad Bishop65ffffa2016-11-29 12:31:31 -0500193} // namespace manager
194} // namespace inventory
195} // namespace phosphor
196
197// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4