added support for onChange report

Report is now notified when metric changes and updates reading values.

Tested:
  - Added new unit tests
  - OnChange report updates Readings when metric values changes

Change-Id: I3be9ef7aa0486cb15bac627aa1de5cc632613b3b
Signed-off-by: Krzysztof Grobelny <krzysztof.grobelny@intel.com>
diff --git a/src/utils/ensure.hpp b/src/utils/ensure.hpp
new file mode 100644
index 0000000..cbe69c5
--- /dev/null
+++ b/src/utils/ensure.hpp
@@ -0,0 +1,69 @@
+#pragma once
+
+#include <optional>
+#include <utility>
+
+namespace utils
+{
+
+template <class F>
+struct Ensure
+{
+    Ensure() = default;
+
+    template <class U>
+    Ensure(U&& functor) : functor(std::forward<U>(functor))
+    {}
+
+    Ensure(F functor) : functor(std::move(functor))
+    {}
+
+    Ensure(Ensure&& other) : functor(std::move(other.functor))
+    {
+        other.functor = std::nullopt;
+    }
+
+    Ensure(const Ensure&) = delete;
+
+    ~Ensure()
+    {
+        clear();
+    }
+
+    template <class U>
+    Ensure& operator=(U&& other)
+    {
+        clear();
+        functor = std::move(other);
+        return *this;
+    }
+
+    Ensure& operator=(Ensure&& other)
+    {
+        clear();
+        std::swap(functor, other.functor);
+        return *this;
+    }
+
+    Ensure& operator=(std::nullptr_t)
+    {
+        clear();
+        return *this;
+    }
+
+    Ensure& operator=(const Ensure&) = delete;
+
+  private:
+    void clear()
+    {
+        if (functor)
+        {
+            (*functor)();
+            functor = std::nullopt;
+        }
+    }
+
+    std::optional<F> functor;
+};
+
+} // namespace utils