xref: /openbmc/telemetry/src/utils/conversion.hpp (revision 405c1e4b)
1 #pragma once
2 
3 #include <algorithm>
4 #include <array>
5 #include <stdexcept>
6 #include <string>
7 
8 namespace utils
9 {
10 
11 template <class T, T first, T last>
12 inline T toEnum(std::underlying_type_t<T> x)
13 {
14     if (x < static_cast<std::underlying_type_t<T>>(first) ||
15         x > static_cast<std::underlying_type_t<T>>(last))
16     {
17         throw std::out_of_range("Value is not in range of enum");
18     }
19     return static_cast<T>(x);
20 }
21 
22 template <class T>
23 inline std::underlying_type_t<T> toUnderlying(T value)
24 {
25     return static_cast<std::underlying_type_t<T>>(value);
26 }
27 
28 template <class T, size_t N>
29 inline T stringToEnum(const std::array<std::pair<std::string_view, T>, N>& data,
30                       const std::string& value)
31 {
32     auto it = std::find_if(
33         std::begin(data), std::end(data),
34         [&value](const auto& item) { return item.first == value; });
35     if (it == std::end(data))
36     {
37         throw std::out_of_range("Value is not in range of enum");
38     }
39     return it->second;
40 }
41 
42 template <class T, size_t N>
43 inline std::string_view
44     enumToString(const std::array<std::pair<std::string_view, T>, N>& data,
45                  T value)
46 {
47     auto it = std::find_if(
48         std::begin(data), std::end(data),
49         [value](const auto& item) { return item.second == value; });
50     if (it == std::end(data))
51     {
52         throw std::out_of_range("Value is not in range of enum");
53     }
54     return it->first;
55 }
56 
57 } // namespace utils
58