xref: /openbmc/phosphor-inventory-manager/functor.hpp (revision 51aff45e80ec084fb86c634ef84f6ce0a0bb5624)
1c1f4798dSBrad Bishop #pragma once
2c1f4798dSBrad Bishop 
3a680d1efSPatrick Venture #include "types.hpp"
4a680d1efSPatrick Venture #include "utils.hpp"
5a680d1efSPatrick Venture 
6c1f4798dSBrad Bishop #include <sdbusplus/bus.hpp>
7a83db30eSBrad Bishop 
8a83db30eSBrad Bishop #include <memory>
9a680d1efSPatrick Venture #include <utility>
10c1f4798dSBrad Bishop 
11c1f4798dSBrad Bishop namespace phosphor
12c1f4798dSBrad Bishop {
13c1f4798dSBrad Bishop namespace inventory
14c1f4798dSBrad Bishop {
15c1f4798dSBrad Bishop namespace manager
16c1f4798dSBrad Bishop {
17c1f4798dSBrad Bishop 
18c1f4798dSBrad Bishop class Manager;
19c1f4798dSBrad Bishop 
20c1f4798dSBrad Bishop /** @brief make_action
21c1f4798dSBrad Bishop  *
22c1f4798dSBrad Bishop  *  Adapt an action function object.
23c1f4798dSBrad Bishop  *
24c1f4798dSBrad Bishop  *  @param[in] action - The action being adapted.
25c1f4798dSBrad Bishop  *  @returns - The adapted action.
26c1f4798dSBrad Bishop  *
27c1f4798dSBrad Bishop  *  @tparam T - The type of the action being adapted.
28c1f4798dSBrad Bishop  */
29a680d1efSPatrick Venture template <typename T>
make_action(T && action)30a680d1efSPatrick Venture auto make_action(T&& action)
31c1f4798dSBrad Bishop {
32c1f4798dSBrad Bishop     return Action(std::forward<T>(action));
33c1f4798dSBrad Bishop }
34c1f4798dSBrad Bishop 
35c1f4798dSBrad Bishop /** @brief make_filter
36c1f4798dSBrad Bishop  *
37c1f4798dSBrad Bishop  *  Adapt a filter function object.
38c1f4798dSBrad Bishop  *
39c1f4798dSBrad Bishop  *  @param[in] filter - The filter being adapted.
40c1f4798dSBrad Bishop  *  @returns - The adapted filter.
41c1f4798dSBrad Bishop  *
42c1f4798dSBrad Bishop  *  @tparam T - The type of the filter being adapted.
43c1f4798dSBrad Bishop  */
44a680d1efSPatrick Venture template <typename T>
make_filter(T && filter)45a680d1efSPatrick Venture auto make_filter(T&& filter)
46c1f4798dSBrad Bishop {
47c1f4798dSBrad Bishop     return Filter(std::forward<T>(filter));
48c1f4798dSBrad Bishop }
49c1f4798dSBrad Bishop 
50d0f48adcSBrad Bishop /** @brief make_path_condition
51d0f48adcSBrad Bishop  *
52d0f48adcSBrad Bishop  *  Adapt a path_condition function object.
53d0f48adcSBrad Bishop  *
54d0f48adcSBrad Bishop  *  @param[in] filter - The functor being adapted.
55d0f48adcSBrad Bishop  *  @returns - The adapted functor.
56d0f48adcSBrad Bishop  *
57d0f48adcSBrad Bishop  *  @tparam T - The type of the functor being adapted.
58d0f48adcSBrad Bishop  */
59a680d1efSPatrick Venture template <typename T>
make_path_condition(T && condition)60a680d1efSPatrick Venture auto make_path_condition(T&& condition)
61d0f48adcSBrad Bishop {
62d0f48adcSBrad Bishop     return PathCondition(std::forward<T>(condition));
63d0f48adcSBrad Bishop }
64d0f48adcSBrad Bishop 
65f094d442SMatthew Barth /** @brief make_get_property
66f094d442SMatthew Barth  *
67f094d442SMatthew Barth  *  Adapt a get_property function object.
68f094d442SMatthew Barth  *
69f094d442SMatthew Barth  *  @param[in] method - The functor being adapted.
70f094d442SMatthew Barth  *  @returns - The adapted functor.
71f094d442SMatthew Barth  *
72f094d442SMatthew Barth  *  @tparam T - The return type of the function object.
73f094d442SMatthew Barth  *  @tparam U - The type of the functor being adapted.
74f094d442SMatthew Barth  */
75f094d442SMatthew Barth template <typename T, typename U>
make_get_property(U && method)76f094d442SMatthew Barth auto make_get_property(U&& method)
77f094d442SMatthew Barth {
78f094d442SMatthew Barth     return GetProperty<T>(std::forward<U>(method));
79f094d442SMatthew Barth }
80f094d442SMatthew Barth 
81d0f48adcSBrad Bishop template <typename T, typename... Args>
callArrayWithStatus(T && container,Args &&...args)82d0f48adcSBrad Bishop auto callArrayWithStatus(T&& container, Args&&... args)
83d0f48adcSBrad Bishop {
84d0f48adcSBrad Bishop     for (auto f : container)
85d0f48adcSBrad Bishop     {
86d0f48adcSBrad Bishop         if (!f(std::forward<Args>(args)...))
87d0f48adcSBrad Bishop         {
88d0f48adcSBrad Bishop             return false;
89d0f48adcSBrad Bishop         }
90d0f48adcSBrad Bishop     }
91d0f48adcSBrad Bishop     return true;
92d0f48adcSBrad Bishop }
93d0f48adcSBrad Bishop 
94c1f4798dSBrad Bishop namespace functor
95c1f4798dSBrad Bishop {
96c1f4798dSBrad Bishop 
97c1f4798dSBrad Bishop /** @brief Destroy objects action.  */
destroyObjects(std::vector<const char * > && paths,std::vector<PathCondition> && conditions)98615b2a8fSBrad Bishop inline auto destroyObjects(std::vector<const char*>&& paths,
99d0f48adcSBrad Bishop                            std::vector<PathCondition>&& conditions)
100c1f4798dSBrad Bishop {
101615b2a8fSBrad Bishop     return [=](auto& b, auto& m) {
102d0f48adcSBrad Bishop         for (const auto& p : paths)
103d0f48adcSBrad Bishop         {
104d0f48adcSBrad Bishop             if (callArrayWithStatus(conditions, p, b, m))
105d0f48adcSBrad Bishop             {
106d0f48adcSBrad Bishop                 m.destroyObjects({p});
107d0f48adcSBrad Bishop             }
108d0f48adcSBrad Bishop         }
109c1f4798dSBrad Bishop     };
110c1f4798dSBrad Bishop }
111c1f4798dSBrad Bishop 
112c1f4798dSBrad Bishop /** @brief Create objects action.  */
113615b2a8fSBrad Bishop inline auto
createObjects(std::map<sdbusplus::message::object_path,Object> && objs)114615b2a8fSBrad Bishop     createObjects(std::map<sdbusplus::message::object_path, Object>&& objs)
115c1f4798dSBrad Bishop {
116615b2a8fSBrad Bishop     return [=](auto&, auto& m) { m.createObjects(objs); };
117c1f4798dSBrad Bishop }
118c1f4798dSBrad Bishop 
119c1f4798dSBrad Bishop /** @brief Set a property action.
120c1f4798dSBrad Bishop  *
121c1f4798dSBrad Bishop  *  Invoke the requested method with a reference to the requested
122c1f4798dSBrad Bishop  *  sdbusplus server binding interface as a parameter.
123c1f4798dSBrad Bishop  *
124c1f4798dSBrad Bishop  *  @tparam T - The sdbusplus server binding interface type.
125c1f4798dSBrad Bishop  *  @tparam U - The type of the sdbusplus server binding member
126c1f4798dSBrad Bishop  *      function that sets the property.
127c1f4798dSBrad Bishop  *  @tparam V - The property value type.
128c1f4798dSBrad Bishop  *
129c1f4798dSBrad Bishop  *  @param[in] paths - The DBus paths on which the property should
130c1f4798dSBrad Bishop  *      be set.
131c1f4798dSBrad Bishop  *  @param[in] iface - The DBus interface hosting the property.
132c1f4798dSBrad Bishop  *  @param[in] member - Pointer to sdbusplus server binding member.
133c1f4798dSBrad Bishop  *  @param[in] value - The value the property should be set to.
134c1f4798dSBrad Bishop  *
135c1f4798dSBrad Bishop  *  @returns - A function object that sets the requested property
136c1f4798dSBrad Bishop  *      to the requested value.
137c1f4798dSBrad Bishop  */
138c1f4798dSBrad Bishop template <typename T, typename U, typename V>
setProperty(std::vector<const char * > && paths,std::vector<PathCondition> && conditions,const char * iface,U && member,V && value)139615b2a8fSBrad Bishop auto setProperty(std::vector<const char*>&& paths,
140615b2a8fSBrad Bishop                  std::vector<PathCondition>&& conditions, const char* iface,
141615b2a8fSBrad Bishop                  U&& member, V&& value)
142c1f4798dSBrad Bishop {
143c1f4798dSBrad Bishop     // The manager is the only parameter passed to actions.
144c1f4798dSBrad Bishop     // Bind the path, interface, interface member function pointer,
145c1f4798dSBrad Bishop     // and value to a lambda.  When it is called, forward the
146c1f4798dSBrad Bishop     // path, interface and value on to the manager member function.
147a680d1efSPatrick Venture     return [paths, conditions = conditions, iface, member,
148a680d1efSPatrick Venture             value = std::forward<V>(value)](auto& b, auto& m) {
149c1f4798dSBrad Bishop         for (auto p : paths)
150c1f4798dSBrad Bishop         {
151d0f48adcSBrad Bishop             if (callArrayWithStatus(conditions, p, b, m))
152d0f48adcSBrad Bishop             {
153615b2a8fSBrad Bishop                 m.template invokeMethod<T>(p, iface, member, value);
154c1f4798dSBrad Bishop             }
155d0f48adcSBrad Bishop         }
156c1f4798dSBrad Bishop     };
157c1f4798dSBrad Bishop }
158c1f4798dSBrad Bishop 
159f094d442SMatthew Barth /** @brief Get a property.
160f094d442SMatthew Barth  *
161f094d442SMatthew Barth  *  Invoke the requested method with a reference to the requested
162f094d442SMatthew Barth  *  sdbusplus server binding interface as a parameter.
163f094d442SMatthew Barth  *
164f094d442SMatthew Barth  *  @tparam T - The sdbusplus server binding interface type.
165f094d442SMatthew Barth  *  @tparam U - The type of the sdbusplus server binding member
166f094d442SMatthew Barth  *      function that sets the property.
167f094d442SMatthew Barth  *
168f094d442SMatthew Barth  *  @param[in] path - The DBus path to get the property from.
169f094d442SMatthew Barth  *  @param[in] iface - The DBus interface hosting the property.
170f094d442SMatthew Barth  *  @param[in] member - Pointer to sdbusplus server binding member.
171f094d442SMatthew Barth  *  @param[in] prop - The property name to get the value from.
172f094d442SMatthew Barth  *
173f094d442SMatthew Barth  *  @returns - A function object that gets the requested property.
174f094d442SMatthew Barth  */
175f094d442SMatthew Barth template <typename T, typename U>
getProperty(const char * path,const char * iface,U && member,const char * prop)176f094d442SMatthew Barth inline auto getProperty(const char* path, const char* iface, U&& member,
177f094d442SMatthew Barth                         const char* prop)
178f094d442SMatthew Barth {
179f094d442SMatthew Barth     return [path, iface, member, prop](auto& mgr) {
180f094d442SMatthew Barth         return mgr.template invokeMethod<T>(path, iface, member, prop);
181f094d442SMatthew Barth     };
182f094d442SMatthew Barth }
183f094d442SMatthew Barth 
184c1f4798dSBrad Bishop /** @struct PropertyChangedCondition
185c1f4798dSBrad Bishop  *  @brief Match filter functor that tests a property value.
186c1f4798dSBrad Bishop  *
187c1f4798dSBrad Bishop  *  @tparam T - The type of the property being tested.
188c1f4798dSBrad Bishop  *  @tparam U - The type of the condition checking functor.
189c1f4798dSBrad Bishop  */
190a680d1efSPatrick Venture template <typename T, typename U>
191a680d1efSPatrick Venture struct PropertyChangedCondition
192c1f4798dSBrad Bishop {
193c1f4798dSBrad Bishop     PropertyChangedCondition() = delete;
194c1f4798dSBrad Bishop     ~PropertyChangedCondition() = default;
195c1f4798dSBrad Bishop     PropertyChangedCondition(const PropertyChangedCondition&) = default;
196615b2a8fSBrad Bishop     PropertyChangedCondition&
197615b2a8fSBrad Bishop         operator=(const PropertyChangedCondition&) = default;
198c1f4798dSBrad Bishop     PropertyChangedCondition(PropertyChangedCondition&&) = default;
199c1f4798dSBrad Bishop     PropertyChangedCondition& operator=(PropertyChangedCondition&&) = default;
PropertyChangedConditionphosphor::inventory::manager::functor::PropertyChangedCondition200c1f4798dSBrad Bishop     PropertyChangedCondition(const char* iface, const char* property,
201c1f4798dSBrad Bishop                              U&& condition) :
202*d8fba8beSPatrick Williams         _iface(iface), _property(property),
203*d8fba8beSPatrick Williams         _condition(std::forward<U>(condition))
204a83db30eSBrad Bishop     {}
205c1f4798dSBrad Bishop 
206c1f4798dSBrad Bishop     /** @brief Test a property value.
207c1f4798dSBrad Bishop      *
208c1f4798dSBrad Bishop      * Extract the property from the PropertiesChanged
209c1f4798dSBrad Bishop      * message and run the condition test.
210c1f4798dSBrad Bishop      */
operator ()phosphor::inventory::manager::functor::PropertyChangedCondition211563306f6SPatrick Williams     bool operator()(sdbusplus::bus_t&, sdbusplus::message_t& msg,
212c1f4798dSBrad Bishop                     Manager&) const
213c1f4798dSBrad Bishop     {
21455f9eae4SPatrick Williams         std::map<std::string, std::variant<T>> properties;
215c1f4798dSBrad Bishop         const char* iface = nullptr;
216c1f4798dSBrad Bishop 
217c1f4798dSBrad Bishop         msg.read(iface);
218c1f4798dSBrad Bishop         if (!iface || strcmp(iface, _iface))
219c1f4798dSBrad Bishop         {
220c1f4798dSBrad Bishop             return false;
221c1f4798dSBrad Bishop         }
222c1f4798dSBrad Bishop 
223c1f4798dSBrad Bishop         msg.read(properties);
224c1f4798dSBrad Bishop         auto it = properties.find(_property);
225c1f4798dSBrad Bishop         if (it == properties.cend())
226c1f4798dSBrad Bishop         {
227c1f4798dSBrad Bishop             return false;
228c1f4798dSBrad Bishop         }
229c1f4798dSBrad Bishop 
23026f8668dSPatrick Williams         return _condition(std::forward<T>(std::get<T>(it->second)));
231c1f4798dSBrad Bishop     }
232c1f4798dSBrad Bishop 
233c1f4798dSBrad Bishop   private:
234c1f4798dSBrad Bishop     const char* _iface;
235c1f4798dSBrad Bishop     const char* _property;
236c1f4798dSBrad Bishop     U _condition;
237c1f4798dSBrad Bishop };
238c1f4798dSBrad Bishop 
239c1f4798dSBrad Bishop /** @struct PropertyConditionBase
240c1f4798dSBrad Bishop  *  @brief Match filter functor that tests a property value.
241c1f4798dSBrad Bishop  *
242c1f4798dSBrad Bishop  *  Base class for PropertyCondition - factored out code that
243c1f4798dSBrad Bishop  *  doesn't need to be templated.
244c1f4798dSBrad Bishop  */
245c1f4798dSBrad Bishop struct PropertyConditionBase
246c1f4798dSBrad Bishop {
247c1f4798dSBrad Bishop     PropertyConditionBase() = delete;
248c1f4798dSBrad Bishop     virtual ~PropertyConditionBase() = default;
249c1f4798dSBrad Bishop     PropertyConditionBase(const PropertyConditionBase&) = default;
250c1f4798dSBrad Bishop     PropertyConditionBase& operator=(const PropertyConditionBase&) = default;
251c1f4798dSBrad Bishop     PropertyConditionBase(PropertyConditionBase&&) = default;
252c1f4798dSBrad Bishop     PropertyConditionBase& operator=(PropertyConditionBase&&) = default;
253c1f4798dSBrad Bishop 
254c1f4798dSBrad Bishop     /** @brief Constructor
255c1f4798dSBrad Bishop      *
256c1f4798dSBrad Bishop      *  The service argument can be nullptr.  If something
257c1f4798dSBrad Bishop      *  else is provided the function will call the the
258c1f4798dSBrad Bishop      *  service directly.  If omitted, the function will
259c1f4798dSBrad Bishop      *  look up the service in the ObjectMapper.
260c1f4798dSBrad Bishop      *
261c1f4798dSBrad Bishop      *  @param path - The path of the object containing
262c1f4798dSBrad Bishop      *     the property to be tested.
263c1f4798dSBrad Bishop      *  @param iface - The interface hosting the property
264c1f4798dSBrad Bishop      *     to be tested.
265c1f4798dSBrad Bishop      *  @param property - The property to be tested.
266c1f4798dSBrad Bishop      *  @param service - The DBus service hosting the object.
267c1f4798dSBrad Bishop      */
PropertyConditionBasephosphor::inventory::manager::functor::PropertyConditionBase268615b2a8fSBrad Bishop     PropertyConditionBase(const char* path, const char* iface,
269615b2a8fSBrad Bishop                           const char* property, const char* service) :
270*d8fba8beSPatrick Williams         _path(path ? path : std::string()), _iface(iface), _property(property),
271*d8fba8beSPatrick Williams         _service(service)
272a83db30eSBrad Bishop     {}
273c1f4798dSBrad Bishop 
274c1f4798dSBrad Bishop     /** @brief Forward comparison to type specific implementation. */
275563306f6SPatrick Williams     virtual bool eval(sdbusplus::message_t&) const = 0;
276c1f4798dSBrad Bishop 
277f094d442SMatthew Barth     /** @brief Forward comparison to type specific implementation. */
278f094d442SMatthew Barth     virtual bool eval(Manager&) const = 0;
279f094d442SMatthew Barth 
280c1f4798dSBrad Bishop     /** @brief Test a property value.
281c1f4798dSBrad Bishop      *
282c1f4798dSBrad Bishop      * Make a DBus call and test the value of any property.
283c1f4798dSBrad Bishop      */
284563306f6SPatrick Williams     bool operator()(sdbusplus::bus_t&, sdbusplus::message_t&, Manager&) const;
285c1f4798dSBrad Bishop 
286d0f48adcSBrad Bishop     /** @brief Test a property value.
287d0f48adcSBrad Bishop      *
288d0f48adcSBrad Bishop      * Make a DBus call and test the value of any property.
289d0f48adcSBrad Bishop      */
290563306f6SPatrick Williams     bool operator()(const std::string&, sdbusplus::bus_t&, Manager&) const;
291d0f48adcSBrad Bishop 
292c1f4798dSBrad Bishop   private:
293c1f4798dSBrad Bishop     std::string _path;
294c1f4798dSBrad Bishop     std::string _iface;
295c1f4798dSBrad Bishop     std::string _property;
296c1f4798dSBrad Bishop     const char* _service;
297c1f4798dSBrad Bishop };
298c1f4798dSBrad Bishop 
299c1f4798dSBrad Bishop /** @struct PropertyCondition
300c1f4798dSBrad Bishop  *  @brief Match filter functor that tests a property value.
301c1f4798dSBrad Bishop  *
302c1f4798dSBrad Bishop  *  @tparam T - The type of the property being tested.
303c1f4798dSBrad Bishop  *  @tparam U - The type of the condition checking functor.
304f094d442SMatthew Barth  *  @tparam V - The getProperty functor return type.
305c1f4798dSBrad Bishop  */
306f094d442SMatthew Barth template <typename T, typename U, typename V>
307c1f4798dSBrad Bishop struct PropertyCondition final : public PropertyConditionBase
308c1f4798dSBrad Bishop {
309c1f4798dSBrad Bishop     PropertyCondition() = delete;
310c1f4798dSBrad Bishop     ~PropertyCondition() = default;
311c1f4798dSBrad Bishop     PropertyCondition(const PropertyCondition&) = default;
312c1f4798dSBrad Bishop     PropertyCondition& operator=(const PropertyCondition&) = default;
313c1f4798dSBrad Bishop     PropertyCondition(PropertyCondition&&) = default;
314c1f4798dSBrad Bishop     PropertyCondition& operator=(PropertyCondition&&) = default;
315c1f4798dSBrad Bishop 
316c1f4798dSBrad Bishop     /** @brief Constructor
317c1f4798dSBrad Bishop      *
318f094d442SMatthew Barth      *  The service & getProperty arguments can be nullptrs.
319f094d442SMatthew Barth      *  If something else is provided the function will call the the
320c1f4798dSBrad Bishop      *  service directly.  If omitted, the function will
321c1f4798dSBrad Bishop      *  look up the service in the ObjectMapper.
322f094d442SMatthew Barth      *  The getProperty function will be called to retrieve a property
323f094d442SMatthew Barth      *  value when given and the property is hosted by inventory manager.
324f094d442SMatthew Barth      *  When not given, the condition will default to return that the
325f094d442SMatthew Barth      *  condition failed and will not be executed.
326c1f4798dSBrad Bishop      *
327c1f4798dSBrad Bishop      *  @param path - The path of the object containing
328c1f4798dSBrad Bishop      *     the property to be tested.
329c1f4798dSBrad Bishop      *  @param iface - The interface hosting the property
330c1f4798dSBrad Bishop      *     to be tested.
331c1f4798dSBrad Bishop      *  @param property - The property to be tested.
332c1f4798dSBrad Bishop      *  @param condition - The test to run on the property.
333c1f4798dSBrad Bishop      *  @param service - The DBus service hosting the object.
334f094d442SMatthew Barth      *  @param getProperty - The function to get a property value
335f094d442SMatthew Barth      *     for the condition.
336c1f4798dSBrad Bishop      */
PropertyConditionphosphor::inventory::manager::functor::PropertyCondition337615b2a8fSBrad Bishop     PropertyCondition(const char* path, const char* iface, const char* property,
338f094d442SMatthew Barth                       U&& condition, const char* service,
339f094d442SMatthew Barth                       GetProperty<V>&& getProperty = nullptr) :
340c1f4798dSBrad Bishop         PropertyConditionBase(path, iface, property, service),
341f094d442SMatthew Barth         _condition(std::forward<decltype(condition)>(condition)),
342f094d442SMatthew Barth         _getProperty(getProperty)
343a83db30eSBrad Bishop     {}
344c1f4798dSBrad Bishop 
345c1f4798dSBrad Bishop     /** @brief Test a property value.
346c1f4798dSBrad Bishop      *
347c1f4798dSBrad Bishop      * Make a DBus call and test the value of any property.
348c1f4798dSBrad Bishop      */
evalphosphor::inventory::manager::functor::PropertyCondition349563306f6SPatrick Williams     bool eval(sdbusplus::message_t& msg) const override
350c1f4798dSBrad Bishop     {
35155f9eae4SPatrick Williams         std::variant<T> value;
352c1f4798dSBrad Bishop         msg.read(value);
35326f8668dSPatrick Williams         return _condition(std::forward<T>(std::get<T>(value)));
354c1f4798dSBrad Bishop     }
355c1f4798dSBrad Bishop 
356f094d442SMatthew Barth     /** @brief Retrieve a property value from inventory and test it.
357f094d442SMatthew Barth      *
358f094d442SMatthew Barth      *  Get a property from the inventory manager and test the value.
359f094d442SMatthew Barth      *  Default to fail the test where no function is given to get the
360f094d442SMatthew Barth      *  property from the inventory manager.
361f094d442SMatthew Barth      */
evalphosphor::inventory::manager::functor::PropertyCondition362f094d442SMatthew Barth     bool eval(Manager& mgr) const override
363f094d442SMatthew Barth     {
364f094d442SMatthew Barth         if (_getProperty)
365f094d442SMatthew Barth         {
366f094d442SMatthew Barth             auto variant = _getProperty(mgr);
36726f8668dSPatrick Williams             auto value = std::get<T>(variant);
368f094d442SMatthew Barth             return _condition(std::forward<T>(value));
369f094d442SMatthew Barth         }
370f094d442SMatthew Barth         return false;
371f094d442SMatthew Barth     }
372f094d442SMatthew Barth 
373c1f4798dSBrad Bishop   private:
374c1f4798dSBrad Bishop     U _condition;
375f094d442SMatthew Barth     GetProperty<V> _getProperty;
376c1f4798dSBrad Bishop };
377c1f4798dSBrad Bishop 
378c1f4798dSBrad Bishop /** @brief Implicit type deduction for constructing PropertyChangedCondition. */
379c1f4798dSBrad Bishop template <typename T>
propertyChangedTo(const char * iface,const char * property,T && val)380615b2a8fSBrad Bishop auto propertyChangedTo(const char* iface, const char* property, T&& val)
381c1f4798dSBrad Bishop {
382a680d1efSPatrick Venture     auto condition = [val = std::forward<T>(val)](T&& arg) {
383c1f4798dSBrad Bishop         return arg == val;
384c1f4798dSBrad Bishop     };
385c1f4798dSBrad Bishop     using U = decltype(condition);
386615b2a8fSBrad Bishop     return PropertyChangedCondition<T, U>(iface, property,
387615b2a8fSBrad Bishop                                           std::move(condition));
388c1f4798dSBrad Bishop }
389c1f4798dSBrad Bishop 
390c1f4798dSBrad Bishop /** @brief Implicit type deduction for constructing PropertyCondition.  */
391f094d442SMatthew Barth template <typename T, typename V = InterfaceVariantType>
propertyIs(const char * path,const char * iface,const char * property,T && val,const char * service=nullptr,GetProperty<V> && getProperty=nullptr)392615b2a8fSBrad Bishop auto propertyIs(const char* path, const char* iface, const char* property,
393f094d442SMatthew Barth                 T&& val, const char* service = nullptr,
394f094d442SMatthew Barth                 GetProperty<V>&& getProperty = nullptr)
395c1f4798dSBrad Bishop {
396a680d1efSPatrick Venture     auto condition = [val = std::forward<T>(val)](T&& arg) {
397c1f4798dSBrad Bishop         return arg == val;
398c1f4798dSBrad Bishop     };
399c1f4798dSBrad Bishop     using U = decltype(condition);
400f094d442SMatthew Barth     return PropertyCondition<T, U, V>(path, iface, property,
401f094d442SMatthew Barth                                       std::move(condition), service,
402f094d442SMatthew Barth                                       std::move(getProperty));
403c1f4798dSBrad Bishop }
404c1f4798dSBrad Bishop } // namespace functor
405c1f4798dSBrad Bishop } // namespace manager
406c1f4798dSBrad Bishop } // namespace inventory
407c1f4798dSBrad Bishop } // namespace phosphor
408