blob: cf3b5cf095e8f3b8e92601ba6091682c3ca75900 [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 */
Brad Bishop615b2a82018-03-29 10:32:41 -040014template <typename V> struct MakeVariantVisitor
Brad Bishop9bbfcb12017-02-04 10:51:06 -050015{
16 /** @struct Make
17 * @brief Return variant visitor.
18 *
19 * @tparam T - The variant type to return.
20 * @tparam Arg - The type being visited in the source variant.
21 * @tparam Enable - Overload resolution removal.
22 */
Brad Bishop615b2a82018-03-29 10:32:41 -040023 template <typename T, typename Arg, typename Enable = void> struct Make
Brad Bishop9bbfcb12017-02-04 10:51:06 -050024 {
25 static auto make(Arg&& arg)
26 {
27 throw sdbusplus::message::variant_ns::bad_variant_access(
28 "in MakeVariantVisitor");
29 return T();
30 }
31 };
Brad Bishop65ffffa2016-11-29 12:31:31 -050032
Brad Bishop9bbfcb12017-02-04 10:51:06 -050033 /** @struct Make
34 * @brief Return variant visitor.
35 *
36 * struct Make specialization if Arg is in T (int -> variant<int, char>).
37 */
38 template <typename T, typename Arg>
Brad Bishop615b2a82018-03-29 10:32:41 -040039 struct Make<
40 T, Arg,
41 typename std::enable_if<std::is_convertible<Arg, T>::value>::type>
Brad Bishop9bbfcb12017-02-04 10:51:06 -050042 {
43 static auto make(Arg&& arg)
44 {
45 return T(std::forward<Arg>(arg));
46 }
47 };
48
49 /** @brief Make variant visitor. */
Brad Bishop615b2a82018-03-29 10:32:41 -040050 template <typename Arg> auto operator()(Arg&& arg) const
Brad Bishop9bbfcb12017-02-04 10:51:06 -050051 {
52 return Make<V, Arg>::make(arg);
53 }
54};
55
56/** @brief Convert variants with different contained types.
57 *
58 * @tparam V - The desired variant type.
59 * @tparam Arg - The source variant type.
60 *
61 * @param[in] v - The source variant.
62 * @returns - The converted variant.
63 */
Brad Bishop615b2a82018-03-29 10:32:41 -040064template <typename V, typename Arg> auto convertVariant(Arg&& v)
Brad Bishop9bbfcb12017-02-04 10:51:06 -050065{
66 return sdbusplus::message::variant_ns::apply_visitor(
Brad Bishop615b2a82018-03-29 10:32:41 -040067 MakeVariantVisitor<V>(), v);
Brad Bishop9bbfcb12017-02-04 10:51:06 -050068}
Brad Bishop86521582017-02-15 01:10:15 -050069
70/** @struct CompareFirst
71 * @brief std::pair binary comparison adapter.
72 *
73 * Adapt a binary comparison function to a comparison of
74 * the first pair element.
75 *
76 * @tparam Compare - The function object type being adapted.
77 */
Brad Bishop615b2a82018-03-29 10:32:41 -040078template <typename Compare> struct CompareFirst
Brad Bishop86521582017-02-15 01:10:15 -050079{
80 /** @brief Construct a CompareFirst adapter.
81 *
82 * @param[in] c - The function object being adapted.
83 */
Brad Bishop615b2a82018-03-29 10:32:41 -040084 explicit CompareFirst(Compare&& c) : compare(std::forward<Compare>(c))
85 {
86 }
Brad Bishop86521582017-02-15 01:10:15 -050087
88 /** @brief Compare two pairs adapter.
89 *
90 * @tparam L1 - First pair first_type.
91 * @tparam L2 - First pair second_type.
92 * @tparam R1 - Second pair first_type, convertible to L1.
93 * @tparam R2 - Second pair second_type.
94 *
95 * @param[in] l - The first pair.
96 * @param[in] r - The second pair.
97 *
98 * @returns - The result of the comparison.
99 */
100 template <typename L1, typename L2, typename R1, typename R2>
Brad Bishop615b2a82018-03-29 10:32:41 -0400101 bool operator()(const std::pair<L1, L2>& l,
102 const std::pair<R1, R2>& r) const
Brad Bishop86521582017-02-15 01:10:15 -0500103 {
104 return compare(l.first, r.first);
105 }
106
107 /** @brief Compare one pair adapter.
108 *
109 * @tparam L1 - Pair first_type.
110 * @tparam L2 - Pair second_type.
111 * @tparam R - Convertible to L1 for comparison.
112 *
113 * @param[in] l - The pair.
114 * @param[in] r - To be compared to l.first.
115 *
116 * @returns - The result of the comparison.
117 */
118 template <typename L1, typename L2, typename R>
119 bool operator()(const std::pair<L1, L2>& l, const R& r) const
120 {
121 return compare(l.first, r);
122 }
123
124 /** @brief Compare one pair adapter.
125 *
126 * @tparam L - Convertible to R1 for comparison.
127 * @tparam R1 - Pair first_type.
128 * @tparam R2 - Pair second_type.
129 *
130 * @param[in] l - To be compared to r.first.
131 * @param[in] r - The pair.
132 *
133 * @returns - The result of the comparison.
134 */
135 template <typename L, typename R1, typename R2>
136 bool operator()(const L& l, const std::pair<R1, R2>& r) const
137 {
138 return compare(l, r.first);
139 }
140
141 /* @brief The function being adapted. */
142 Compare compare;
143};
144
145/* @brief Implicit template instantation wrapper for CompareFirst. */
Brad Bishop615b2a82018-03-29 10:32:41 -0400146template <typename Compare> CompareFirst<Compare> compareFirst(Compare&& c)
Brad Bishop86521582017-02-15 01:10:15 -0500147{
148 return CompareFirst<Compare>(std::forward<Compare>(c));
149}
150
151/** @struct RelPathCompare
152 * @brief Compare two strings after removing an optional prefix.
153 */
154struct RelPathCompare
155{
156 /** @brief Construct a RelPathCompare comparison functor.
157 *
158 * @param[in] p - The prefix to check for and remove.
159 */
Brad Bishop615b2a82018-03-29 10:32:41 -0400160 explicit RelPathCompare(const char* p) : prefix(p)
161 {
162 }
Brad Bishop86521582017-02-15 01:10:15 -0500163
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