1 #pragma once
2 
3 #include "callback.hpp"
4 #include "data_types.hpp"
5 
6 namespace phosphor
7 {
8 namespace dbus
9 {
10 namespace monitoring
11 {
12 
13 /** @class CountCondition
14  *  @brief Count properties that satisfy a condition.
15  *
16  *  When invoked, a count class instance performs its condition
17  *  test in two passes.
18  *
19  *  In pass one, apply a C++ relational operator to the value of
20  *  each property in the index and a value provided by the
21  *  configuration file.
22  *
23  *  Count the number of properties that pass the test in pass
24  *  one.  In pass two, apply a second C++ relational operator
25  *  to the number of properties that pass the test from pass one
26  *  to a count provided by the configuration file.
27  */
28 template <typename T>
29 class CountCondition : public IndexedConditional
30 {
31     public:
32         CountCondition() = delete;
33         CountCondition(const CountCondition&) = default;
34         CountCondition(CountCondition&&) = default;
35         CountCondition& operator=(const CountCondition&) = default;
36         CountCondition& operator=(CountCondition&&) = default;
37         ~CountCondition() = default;
38 
39         CountCondition(
40             const PropertyIndex& conditionIndex,
41             const std::function<bool(size_t)>& _countOp,
42             const std::function<bool(T)>& _propertyOp) :
43             IndexedConditional(conditionIndex),
44             countOp(_countOp),
45             propertyOp(_propertyOp) {}
46 
47         bool operator()() override
48         {
49             // Count the number of properties in the index that
50             // pass the condition specified in the config file.
51             auto count = std::count_if(
52                              index.cbegin(),
53                              index.cend(),
54                              [this](const auto & item)
55             // *INDENT-OFF*
56                              {
57                                  const auto& storage = std::get<2>(
58                                      item.second);
59                                  // Don't count properties that don't exist.
60                                  if (storage.get().empty())
61                                  {
62                                      return false;
63                                  }
64                                  const auto& value = any_ns::any_cast<T>(
65                                      storage);
66                                  return propertyOp(value);
67                              });
68             // *INDENT-ON*
69 
70             // Now apply the count condition to the count.
71             return countOp(count);
72         }
73 
74     private:
75         /** @brief The comparison to perform on the count. */
76         std::function<bool(size_t)> countOp;
77         /** @brief The comparison to perform on each property. */
78         std::function<bool(T)> propertyOp;
79 };
80 } // namespace monitoring
81 } // namespace dbus
82 } // namespace phosphor
83