added property SupportedOperationTypes

- removed OperationType::single
- for backward compatibility incomming OperationType::single alted to
  produce same output functionality
- added property SupportedOperationTypes to ReportManager interface

Tested:
- In cases where OperationType::single is used same MetricValues are
  produced
- New property is visible on dbus

Change-Id: I838581c954abc0d8401e0ed530ce7e9c8013860b
Signed-off-by: Krzysztof Grobelny <krzysztof.grobelny@intel.com>
diff --git a/src/details/collection_function.cpp b/src/details/collection_function.cpp
index 360f082..5134b0e 100644
--- a/src/details/collection_function.cpp
+++ b/src/details/collection_function.cpp
@@ -5,23 +5,6 @@
 namespace details
 {
 
-class FunctionSingle : public CollectionFunction
-{
-  public:
-    double calculate(const std::vector<ReadingItem>& readings,
-                     Milliseconds) const override
-    {
-        return readings.back().second;
-    }
-
-    double calculateForStartupInterval(std::vector<ReadingItem>& readings,
-                                       Milliseconds) const override
-    {
-        readings.assign({readings.back()});
-        return readings.back().second;
-    }
-};
-
 class FunctionMinimum : public CollectionFunction
 {
   public:
@@ -175,8 +158,6 @@
 
     switch (operationType)
     {
-        case OperationType::single:
-            return std::make_shared<FunctionSingle>();
         case OperationType::min:
             return std::make_shared<FunctionMinimum>();
         case OperationType::max:
diff --git a/src/report_factory.cpp b/src/report_factory.cpp
index df71fa0..261fc75 100644
--- a/src/report_factory.cpp
+++ b/src/report_factory.cpp
@@ -97,6 +97,12 @@
         {
             operationType = utils::enumToString(OperationType::avg);
         }
+        else if (operationType == "SINGLE")
+        {
+            operationType = utils::enumToString(OperationType::avg);
+            collectionTimeScope =
+                utils::enumToString(CollectionTimeScope::point);
+        }
 
         if (collectionTimeScope.empty())
         {
diff --git a/src/report_manager.cpp b/src/report_manager.cpp
index df60075..31363c4 100644
--- a/src/report_manager.cpp
+++ b/src/report_manager.cpp
@@ -52,6 +52,15 @@
             dbusIface.register_property_r(
                 "MinInterval", uint64_t{}, sdbusplus::vtable::property_::const_,
                 [](const auto&) -> uint64_t { return minInterval.count(); });
+            dbusIface.register_property_r(
+                "SupportedOperationTypes", std::vector<std::string>{},
+                sdbusplus::vtable::property_::const_,
+                [](const auto&) -> std::vector<std::string> {
+                    return utils::transform<std::vector<std::string>>(
+                        utils::convDataOperationType, [](const auto& item) {
+                            return std::string(item.first);
+                        });
+                });
 
             dbusIface.register_method(
                 "AddReport", [this](boost::asio::yield_context& yield,
diff --git a/src/types/operation_type.hpp b/src/types/operation_type.hpp
index 29bceb4..6d19620 100644
--- a/src/types/operation_type.hpp
+++ b/src/types/operation_type.hpp
@@ -8,7 +8,6 @@
 
 enum class OperationType : uint32_t
 {
-    single,
     max,
     min,
     avg,
@@ -18,18 +17,15 @@
 namespace utils
 {
 
-constexpr std::array<std::pair<std::string_view, OperationType>, 5>
-    convDataOperationType = {
-        {std::make_pair<std::string_view, OperationType>("SINGLE",
-                                                         OperationType::single),
-         std::make_pair<std::string_view, OperationType>("Maximum",
-                                                         OperationType::max),
-         std::make_pair<std::string_view, OperationType>("Minimum",
-                                                         OperationType::min),
-         std::make_pair<std::string_view, OperationType>("Average",
-                                                         OperationType::avg),
-         std::make_pair<std::string_view, OperationType>("Summation",
-                                                         OperationType::sum)}};
+constexpr std::array<std::pair<std::string_view, OperationType>, 4>
+    convDataOperationType = {{std::make_pair<std::string_view, OperationType>(
+                                  "Maximum", OperationType::max),
+                              std::make_pair<std::string_view, OperationType>(
+                                  "Minimum", OperationType::min),
+                              std::make_pair<std::string_view, OperationType>(
+                                  "Average", OperationType::avg),
+                              std::make_pair<std::string_view, OperationType>(
+                                  "Summation", OperationType::sum)}};
 
 inline OperationType
     toOperationType(std::underlying_type_t<OperationType> value)
diff --git a/src/utils/transform.hpp b/src/utils/transform.hpp
index b354b0f..4a28950 100644
--- a/src/utils/transform.hpp
+++ b/src/utils/transform.hpp
@@ -9,34 +9,19 @@
 {
 
 template <class T>
-struct has_member_reserve
+concept has_member_reserve = requires(T t)
 {
-    template <class U>
-    static U& ref();
-
-    template <class U>
-    static std::true_type check(decltype(ref<U>().reserve(size_t{}))*);
-
-    template <class>
-    static std::false_type check(...);
-
-    static constexpr bool value =
-        decltype(check<std::decay_t<T>>(nullptr))::value;
+    t.reserve(size_t{});
 };
 
-template <class T>
-constexpr bool has_member_reserve_v = has_member_reserve<T>::value;
-
 } // namespace detail
 
-template <template <class, class...> class Container, class T, class... Args,
-          class F>
-auto transform(const Container<T, Args...>& container, F&& functor)
+template <class R, class Container, class F>
+auto transform(const Container& container, F&& functor)
 {
-    using R = decltype(functor(*container.begin()));
+    auto result = R{};
 
-    Container<R> result;
-    if constexpr (detail::has_member_reserve_v<Container<T, Args...>>)
+    if constexpr (detail::has_member_reserve<decltype(result)>)
     {
         result.reserve(container.size());
     }
@@ -46,4 +31,12 @@
     return result;
 }
 
+template <template <class, class...> class Container, class T, class... Args,
+          class F>
+auto transform(const Container<T, Args...>& container, F&& functor)
+{
+    using R = Container<decltype(functor(*container.begin()))>;
+    return transform<R>(container, std::forward<F>(functor));
+}
+
 } // namespace utils