xref: /openbmc/phosphor-host-ipmid/include/ipmid/message/types.hpp (revision fbc6c9d743d22682f3753841071b8460ad50b5d9)
1  /**
2   * Copyright © 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  #pragma once
17  
18  #include <boost/multiprecision/cpp_int.hpp>
19  #include <boost/version.hpp>
20  #include <ipmid/utility.hpp>
21  
22  #include <bitset>
23  #include <tuple>
24  
25  #if BOOST_VERSION < 107900
26  using bitcount_t = unsigned;
27  #else
28  using bitcount_t = std::size_t;
29  #endif
30  
31  // unsigned fixed-bit sizes
32  template <bitcount_t N>
33  using fixed_uint_t =
34      boost::multiprecision::number<boost::multiprecision::cpp_int_backend<
35          N, N, boost::multiprecision::unsigned_magnitude,
36          boost::multiprecision::unchecked, void>>;
37  // signed fixed-bit sizes
38  template <bitcount_t N>
39  using fixed_int_t =
40      boost::multiprecision::number<boost::multiprecision::cpp_int_backend<
41          N, N, boost::multiprecision::signed_magnitude,
42          boost::multiprecision::unchecked, void>>;
43  
44  using uint1_t = fixed_uint_t<1>;
45  using uint2_t = fixed_uint_t<2>;
46  using uint3_t = fixed_uint_t<3>;
47  using uint4_t = fixed_uint_t<4>;
48  using uint5_t = fixed_uint_t<5>;
49  using uint6_t = fixed_uint_t<6>;
50  using uint7_t = fixed_uint_t<7>;
51  // native uint8_t
52  using uint9_t = fixed_uint_t<9>;
53  using uint10_t = fixed_uint_t<10>;
54  using uint11_t = fixed_uint_t<11>;
55  using uint12_t = fixed_uint_t<12>;
56  using uint13_t = fixed_uint_t<13>;
57  using uint14_t = fixed_uint_t<14>;
58  using uint15_t = fixed_uint_t<15>;
59  // native uint16_t
60  using uint24_t = fixed_uint_t<24>;
61  
62  // signed fixed-bit sizes
63  using int2_t = fixed_int_t<2>;
64  using int3_t = fixed_int_t<3>;
65  using int4_t = fixed_int_t<4>;
66  using int5_t = fixed_int_t<5>;
67  using int6_t = fixed_int_t<6>;
68  using int7_t = fixed_int_t<7>;
69  // native int8_t
70  using int9_t = fixed_int_t<9>;
71  using int10_t = fixed_int_t<10>;
72  using int11_t = fixed_int_t<11>;
73  using int12_t = fixed_int_t<12>;
74  using int13_t = fixed_int_t<13>;
75  using int14_t = fixed_int_t<14>;
76  using int15_t = fixed_int_t<15>;
77  // native int16_t
78  using int24_t = fixed_int_t<24>;
79  
80  // bool is more efficient than a uint1_t
81  using bit = bool;
82  
83  // Mechanism for going from uint7_t, int7_t, or std::bitset<7> to 7 bits
84  // use nrFixedBits<uint7_t> or nrFixedBits<decltype(u7)>
85  namespace types
86  {
87  namespace details
88  {
89  
90  template <bitcount_t N>
91  struct Size
92  {
93      static constexpr bitcount_t value = N;
94  };
95  
96  template <bitcount_t Bits>
97  constexpr auto getNrBits(const fixed_int_t<Bits>&) -> Size<Bits>;
98  template <bitcount_t Bits>
99  constexpr auto getNrBits(const fixed_uint_t<Bits>&) -> Size<Bits>;
100  template <bitcount_t Bits>
101  constexpr auto getNrBits(const std::bitset<Bits>&) -> Size<Bits>;
102  
103  template <typename U>
104  using underlying_t =
105      typename std::conditional_t<std::is_enum_v<U>, std::underlying_type<U>,
106                                  std::enable_if<true, U>>::type;
107  
108  } // namespace details
109  
110  /**
111   * @brief mechanism to get N from a type like fixed_int_t<N>
112   *
113   * helper template to extract N from a fixed_(u)int_t variable
114   *
115   * @tparam T - a type of fixed_int_t<N> or fixed_unint_t<N>
116   *
117   * @return size_t - evaluates to a constexpr size_t of N
118   */
119  template <typename T>
120  constexpr auto nrFixedBits =
121      decltype(details::getNrBits(std::declval<T>()))::value;
122  
123  /**
124   * @brief Converts a number or enum class to another
125   * @tparam R - The output type
126   * @tparam T - The input type
127   * @param t - An enum or integer value to cast
128   * @return The value in R form
129   */
130  template <typename R, typename T>
enum_cast(T t)131  inline R enum_cast(T t)
132  {
133      auto tu = static_cast<details::underlying_t<T>>(t);
134      auto ru = static_cast<details::underlying_t<R>>(tu);
135      return static_cast<R>(ru);
136  }
137  
138  } // namespace types
139