Create Filters class to store filter functions

Enhanced the generated code to now store the filter functions within an
array contained in a struct similar to other configured parameters.
This allows the generated property watches to use an index within that
array to access a pointer to a Filters class containing a given set of
filter functions. The set of filter functions would then be applied
against all the properties being watched.

Tested:
    Generated code provides structure needed to access filter functions
    Filter functions filter property values that fail the filter(s)

Change-Id: I8f1f882704de521f2ab393530ad7ef096314975d
Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
diff --git a/src/filters.hpp b/src/filters.hpp
new file mode 100644
index 0000000..c7a5bcf
--- /dev/null
+++ b/src/filters.hpp
@@ -0,0 +1,88 @@
+#pragma once
+
+#include "data_types.hpp"
+
+#include <algorithm>
+#include <functional>
+
+namespace phosphor
+{
+namespace dbus
+{
+namespace monitoring
+{
+
+/** @class Filters
+ *  @brief Filter interface
+ *
+ *  Filters of any type can be applied to property value changes.
+ */
+class Filters
+{
+  public:
+    Filters() = default;
+    Filters(const Filters&) = delete;
+    Filters(Filters&&) = default;
+    Filters& operator=(const Filters&) = delete;
+    Filters& operator=(Filters&&) = default;
+    virtual ~Filters() = default;
+
+    /** @brief Apply filter operations to a property value. */
+    virtual bool operator()(const any_ns::any& value) = 0;
+};
+
+/** @class OperandFilters
+ *  @brief Filter property values utilzing operand based functions.
+ *
+ *  When configured, an operand filter is applied to a property value each
+ *  time it changes to determine if that property value should be filtered
+ *  from being stored or used within a given callback function.
+ */
+template <typename T>
+class OperandFilters : public Filters
+{
+  public:
+    OperandFilters() = delete;
+    OperandFilters(const OperandFilters&) = delete;
+    OperandFilters(OperandFilters&&) = default;
+    OperandFilters& operator=(const OperandFilters&) = delete;
+    OperandFilters& operator=(OperandFilters&&) = default;
+    virtual ~OperandFilters() = default;
+    explicit OperandFilters(const std::vector<std::function<bool(T)>>& _ops) :
+        Filters(), ops(std::move(_ops))
+    {
+    }
+
+    bool operator()(const any_ns::any& value) override
+    {
+        for (const auto& filterOps : ops)
+        {
+            try
+            {
+                // Apply filter operand to property value
+                if (!filterOps(any_ns::any_cast<T>(value)))
+                {
+                    // Property value should be filtered
+                    return true;
+                }
+            }
+            catch (const any_ns::bad_any_cast& bac)
+            {
+                // Unable to cast property value to filter value type
+                // to check filter, continue to next filter op
+                continue;
+            }
+        }
+
+        // Property value should not be filtered
+        return false;
+    }
+
+  private:
+    /** @brief List of operand based filter functions. */
+    const std::vector<std::function<bool(T)>> ops;
+};
+
+} // namespace monitoring
+} // namespace dbus
+} // namespace phosphor