xref: /openbmc/dbus-sensors/src/VariantVisitors.hpp (revision bd815c7f79301fe3932093bfd799122879122680)
1 /*
2 // Copyright (c) 2018 Intel Corporation
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 */
16 
17 #pragma once
18 #include <boost/type_index.hpp>
19 
20 #include <concepts>
21 #include <stdexcept>
22 #include <string>
23 #include <vector>
24 
25 namespace details
26 {
27 
28 template <typename U>
29 struct VariantToNumericVisitor
30 {
31     template <typename T>
operator ()details::VariantToNumericVisitor32     U operator()(const T& t) const
33     {
34         if constexpr (std::is_arithmetic_v<T>)
35         {
36             return static_cast<U>(t);
37         }
38         throw std::invalid_argument(
39             "Cannot translate type " +
40             boost::typeindex::type_id<T>().pretty_name() + " to " +
41             boost::typeindex::type_id<U>().pretty_name());
42     }
43 };
44 
45 } // namespace details
46 
47 using VariantToFloatVisitor = details::VariantToNumericVisitor<float>;
48 using VariantToIntVisitor = details::VariantToNumericVisitor<int>;
49 using VariantToUnsignedIntVisitor =
50     details::VariantToNumericVisitor<unsigned int>;
51 using VariantToDoubleVisitor = details::VariantToNumericVisitor<double>;
52 
53 struct VariantToStringVisitor
54 {
55     template <typename T>
operator ()VariantToStringVisitor56     std::string operator()(const T& t) const
57     {
58         if constexpr (std::is_same_v<T, std::string>)
59         {
60             return t;
61         }
62         else if constexpr (std::is_arithmetic_v<T>)
63         {
64             return std::to_string(t);
65         }
66         throw std::invalid_argument(
67             "Cannot translate type " +
68             boost::typeindex::type_id<T>().pretty_name() + " to string");
69     }
70 };
71 
72 template <std::integral V, std::integral U>
73 struct VariantToNumArrayVisitor
74 {
75     template <typename T>
operator ()VariantToNumArrayVisitor76     std::vector<V> operator()(const T& t) const
77     {
78         if constexpr (std::is_same_v<T, std::vector<U>>)
79         {
80             std::vector<V> output;
81             output.reserve(t.size());
82 
83             for (const auto& value : t)
84             {
85                 output.push_back(static_cast<V>(value));
86             }
87 
88             return output;
89         }
90         throw std::invalid_argument(
91             "Cannot handle type " +
92             boost::typeindex::type_id<T>().pretty_name() + " to vector<U>");
93     }
94 };
95