1 #pragma once
2 
3 #include "data_types.hpp"
4 
5 #include <algorithm>
6 #include <functional>
7 
8 namespace phosphor
9 {
10 namespace dbus
11 {
12 namespace monitoring
13 {
14 
15 /** @class Filters
16  *  @brief Filter interface
17  *
18  *  Filters of any type can be applied to property value changes.
19  */
20 class Filters
21 {
22   public:
23     Filters() = default;
24     Filters(const Filters&) = delete;
25     Filters(Filters&&) = default;
26     Filters& operator=(const Filters&) = delete;
27     Filters& operator=(Filters&&) = default;
28     virtual ~Filters() = default;
29 
30     /** @brief Apply filter operations to a property value. */
31     virtual bool operator()(const std::any& value) = 0;
32 };
33 
34 /** @class OperandFilters
35  *  @brief Filter property values utilizing operand based functions.
36  *
37  *  When configured, an operand filter is applied to a property value each
38  *  time it changes to determine if that property value should be filtered
39  *  from being stored or used within a given callback function.
40  */
41 template <typename T>
42 class OperandFilters : public Filters
43 {
44   public:
45     OperandFilters() = delete;
46     OperandFilters(const OperandFilters&) = delete;
47     OperandFilters(OperandFilters&&) = default;
48     OperandFilters& operator=(const OperandFilters&) = delete;
49     OperandFilters& operator=(OperandFilters&&) = default;
50     virtual ~OperandFilters() = default;
OperandFilters(const std::vector<std::function<bool (T)>> & _ops)51     explicit OperandFilters(const std::vector<std::function<bool(T)>>& _ops) :
52         Filters(), ops(std::move(_ops))
53     {}
54 
operator ()(const std::any & value)55     bool operator()(const std::any& value) override
56     {
57         for (const auto& filterOps : ops)
58         {
59             try
60             {
61                 // Apply filter operand to property value
62                 if (!filterOps(std::any_cast<T>(value)))
63                 {
64                     // Property value should be filtered
65                     return true;
66                 }
67             }
68             catch (const std::bad_any_cast& bac)
69             {
70                 // Unable to cast property value to filter value type
71                 // to check filter, continue to next filter op
72                 continue;
73             }
74         }
75 
76         // Property value should not be filtered
77         return false;
78     }
79 
80   private:
81     /** @brief List of operand based filter functions. */
82     const std::vector<std::function<bool(T)>> ops;
83 };
84 
85 } // namespace monitoring
86 } // namespace dbus
87 } // namespace phosphor
88