Using enum class instead of string in more places
ReportingType and ReportUpdates are now used as enum class in more
places than before. Changed how this two fields are stored in
persistent configuration. Increased Report::Version to break backward
compatibility. Updated unit tests to verify changed functionality.
Tested:
- All existing tests are passing
Change-Id: I55db205aefbe2b5a69fb7a31ccf11885aaecaaf2
Signed-off-by: Krzysztof Grobelny <krzysztof.grobelny@intel.com>
diff --git a/src/utils/contains.hpp b/src/utils/contains.hpp
new file mode 100644
index 0000000..ea1dd16
--- /dev/null
+++ b/src/utils/contains.hpp
@@ -0,0 +1,32 @@
+#pragma once
+
+#include <algorithm>
+
+namespace utils
+{
+namespace detail
+{
+
+template <class T>
+concept HasMemberFind = requires(T container)
+{
+ container.find(container.begin()->first);
+};
+
+} // namespace detail
+
+template <detail::HasMemberFind T>
+inline bool contains(const T& container,
+ const typename T::value_type::first_type& key)
+{
+ return container.find(key) != container.end();
+}
+
+template <class T>
+inline bool contains(const T& container, const typename T::value_type& key)
+{
+ return std::find(container.begin(), container.end(), key) !=
+ container.end();
+}
+
+} // namespace utils
diff --git a/src/utils/conversion.hpp b/src/utils/conversion.hpp
index 5e8ef81..222b990 100644
--- a/src/utils/conversion.hpp
+++ b/src/utils/conversion.hpp
@@ -8,33 +8,72 @@
namespace utils
{
+template <class T>
+struct EnumTraits
+{
+ [[noreturn]] static void throwConversionError()
+ {
+ throw std::out_of_range("Value is not in range of enum");
+ }
+};
+
template <class T, T first, T last>
inline T toEnum(std::underlying_type_t<T> x)
{
if (x < static_cast<std::underlying_type_t<T>>(first) ||
x > static_cast<std::underlying_type_t<T>>(last))
{
- throw std::out_of_range("Value is not in range of enum");
+ EnumTraits<T>::throwConversionError();
}
return static_cast<T>(x);
}
template <class T>
-inline std::underlying_type_t<T> toUnderlying(T value)
+constexpr inline std::underlying_type_t<T> toUnderlying(T value)
{
return static_cast<std::underlying_type_t<T>>(value);
}
template <class T, size_t N>
-inline T stringToEnum(const std::array<std::pair<std::string_view, T>, N>& data,
- const std::string& value)
+constexpr inline T
+ minEnumValue(std::array<std::pair<std::string_view, T>, N> data)
+{
+ auto min = data[0].second;
+ for (auto [key, value] : data)
+ {
+ if (toUnderlying(min) > toUnderlying(value))
+ {
+ min = value;
+ }
+ }
+ return min;
+}
+
+template <class T, size_t N>
+constexpr inline T
+ maxEnumValue(std::array<std::pair<std::string_view, T>, N> data)
+{
+ auto max = data[0].second;
+ for (auto [key, value] : data)
+ {
+ if (toUnderlying(max) < toUnderlying(value))
+ {
+ max = value;
+ }
+ }
+ return max;
+}
+
+template <class T, size_t N>
+inline T toEnum(const std::array<std::pair<std::string_view, T>, N>& data,
+ const std::string& value)
{
auto it = std::find_if(
std::begin(data), std::end(data),
[&value](const auto& item) { return item.first == value; });
if (it == std::end(data))
{
- throw std::out_of_range("Value is not in range of enum");
+ EnumTraits<T>::throwConversionError();
}
return it->second;
}
@@ -49,7 +88,7 @@
[value](const auto& item) { return item.second == value; });
if (it == std::end(data))
{
- throw std::out_of_range("Value is not in range of enum");
+ EnumTraits<T>::throwConversionError();
}
return it->first;
}
diff --git a/src/utils/conversion_trigger.cpp b/src/utils/conversion_trigger.cpp
index 5aae0d5..aec0f28 100644
--- a/src/utils/conversion_trigger.cpp
+++ b/src/utils/conversion_trigger.cpp
@@ -22,9 +22,9 @@
return utils::transform(arg, [](const auto& thresholdParam) {
const auto& [type, dwellTime, direction, thresholdValue] =
thresholdParam;
- return numeric::LabeledThresholdParam(
- numeric::stringToType(type), dwellTime,
- numeric::stringToDirection(direction), thresholdValue);
+ return numeric::LabeledThresholdParam(numeric::toType(type), dwellTime,
+ numeric::toDirection(direction),
+ thresholdValue);
});
}
@@ -35,8 +35,7 @@
const auto& [userId, severity, dwellTime, thresholdValue] =
thresholdParam;
return discrete::LabeledThresholdParam(
- userId, discrete::stringToSeverity(severity), dwellTime,
- thresholdValue);
+ userId, discrete::toSeverity(severity), dwellTime, thresholdValue);
});
}