1*e73bd0a1SAndrew Jeffery /*
2*e73bd0a1SAndrew Jeffery // Copyright (c) 2018 Intel Corporation
3*e73bd0a1SAndrew Jeffery //
4*e73bd0a1SAndrew Jeffery // Licensed under the Apache License, Version 2.0 (the "License");
5*e73bd0a1SAndrew Jeffery // you may not use this file except in compliance with the License.
6*e73bd0a1SAndrew Jeffery // You may obtain a copy of the License at
7*e73bd0a1SAndrew Jeffery //
8*e73bd0a1SAndrew Jeffery //      http://www.apache.org/licenses/LICENSE-2.0
9*e73bd0a1SAndrew Jeffery //
10*e73bd0a1SAndrew Jeffery // Unless required by applicable law or agreed to in writing, software
11*e73bd0a1SAndrew Jeffery // distributed under the License is distributed on an "AS IS" BASIS,
12*e73bd0a1SAndrew Jeffery // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*e73bd0a1SAndrew Jeffery // See the License for the specific language governing permissions and
14*e73bd0a1SAndrew Jeffery // limitations under the License.
15*e73bd0a1SAndrew Jeffery */
16*e73bd0a1SAndrew Jeffery 
17*e73bd0a1SAndrew Jeffery #pragma once
18*e73bd0a1SAndrew Jeffery #include <boost/type_index.hpp>
19*e73bd0a1SAndrew Jeffery 
20*e73bd0a1SAndrew Jeffery #include <stdexcept>
21*e73bd0a1SAndrew Jeffery #include <string>
22*e73bd0a1SAndrew Jeffery #include <variant>
23*e73bd0a1SAndrew Jeffery 
24*e73bd0a1SAndrew Jeffery namespace details
25*e73bd0a1SAndrew Jeffery {
26*e73bd0a1SAndrew Jeffery 
27*e73bd0a1SAndrew Jeffery template <typename U>
28*e73bd0a1SAndrew Jeffery struct VariantToNumericVisitor
29*e73bd0a1SAndrew Jeffery {
30*e73bd0a1SAndrew Jeffery     template <typename T>
operator ()details::VariantToNumericVisitor31*e73bd0a1SAndrew Jeffery     U operator()(const T& t) const
32*e73bd0a1SAndrew Jeffery     {
33*e73bd0a1SAndrew Jeffery         if constexpr (std::is_arithmetic_v<T>)
34*e73bd0a1SAndrew Jeffery         {
35*e73bd0a1SAndrew Jeffery             return static_cast<U>(t);
36*e73bd0a1SAndrew Jeffery         }
37*e73bd0a1SAndrew Jeffery         throw std::invalid_argument(
38*e73bd0a1SAndrew Jeffery             "Cannot translate type " +
39*e73bd0a1SAndrew Jeffery             boost::typeindex::type_id<T>().pretty_name() + " to " +
40*e73bd0a1SAndrew Jeffery             boost::typeindex::type_id<U>().pretty_name());
41*e73bd0a1SAndrew Jeffery     }
42*e73bd0a1SAndrew Jeffery };
43*e73bd0a1SAndrew Jeffery 
44*e73bd0a1SAndrew Jeffery } // namespace details
45*e73bd0a1SAndrew Jeffery 
46*e73bd0a1SAndrew Jeffery using VariantToFloatVisitor = details::VariantToNumericVisitor<float>;
47*e73bd0a1SAndrew Jeffery using VariantToIntVisitor = details::VariantToNumericVisitor<int>;
48*e73bd0a1SAndrew Jeffery using VariantToUnsignedIntVisitor =
49*e73bd0a1SAndrew Jeffery     details::VariantToNumericVisitor<unsigned int>;
50*e73bd0a1SAndrew Jeffery using VariantToDoubleVisitor = details::VariantToNumericVisitor<double>;
51*e73bd0a1SAndrew Jeffery 
52*e73bd0a1SAndrew Jeffery struct VariantToStringVisitor
53*e73bd0a1SAndrew Jeffery {
54*e73bd0a1SAndrew Jeffery     template <typename T>
operator ()VariantToStringVisitor55*e73bd0a1SAndrew Jeffery     std::string operator()(const T& t) const
56*e73bd0a1SAndrew Jeffery     {
57*e73bd0a1SAndrew Jeffery         if constexpr (std::is_same_v<T, std::string>)
58*e73bd0a1SAndrew Jeffery         {
59*e73bd0a1SAndrew Jeffery             return t;
60*e73bd0a1SAndrew Jeffery         }
61*e73bd0a1SAndrew Jeffery         else if constexpr (std::is_arithmetic_v<T>)
62*e73bd0a1SAndrew Jeffery         {
63*e73bd0a1SAndrew Jeffery             return std::to_string(t);
64*e73bd0a1SAndrew Jeffery         }
65*e73bd0a1SAndrew Jeffery         throw std::invalid_argument(
66*e73bd0a1SAndrew Jeffery             "Cannot translate type " +
67*e73bd0a1SAndrew Jeffery             boost::typeindex::type_id<T>().pretty_name() + " to string");
68*e73bd0a1SAndrew Jeffery     }
69*e73bd0a1SAndrew Jeffery };
70