blob: c53529bd81a644b78bb4b4e02c3c9cd59ac3e79e [file] [log] [blame]
Vernon Mauerye7329c72018-10-08 12:05:16 -07001/**
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
Vernon Mauerye7329c72018-10-08 12:05:16 -070018#include <boost/multiprecision/cpp_int.hpp>
Tim Leeb4905912022-06-18 02:51:13 +080019#include <boost/version.hpp>
Vernon Mauerye7329c72018-10-08 12:05:16 -070020#include <ipmid/utility.hpp>
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -050021
22#include <bitset>
Vernon Mauerye7329c72018-10-08 12:05:16 -070023#include <tuple>
24
Tim Leeb4905912022-06-18 02:51:13 +080025#if BOOST_VERSION < 107900
26using bitcount_t = unsigned;
27#else
28using bitcount_t = std::size_t;
29#endif
30
Vernon Mauerye7329c72018-10-08 12:05:16 -070031// unsigned fixed-bit sizes
Tim Leeb4905912022-06-18 02:51:13 +080032template <bitcount_t N>
Vernon Mauerye7329c72018-10-08 12:05:16 -070033using 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
Tim Leeb4905912022-06-18 02:51:13 +080038template <bitcount_t N>
Vernon Mauerye7329c72018-10-08 12:05:16 -070039using 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
44using uint1_t = fixed_uint_t<1>;
45using uint2_t = fixed_uint_t<2>;
46using uint3_t = fixed_uint_t<3>;
47using uint4_t = fixed_uint_t<4>;
48using uint5_t = fixed_uint_t<5>;
49using uint6_t = fixed_uint_t<6>;
50using uint7_t = fixed_uint_t<7>;
51// native uint8_t
52using uint9_t = fixed_uint_t<9>;
53using uint10_t = fixed_uint_t<10>;
54using uint11_t = fixed_uint_t<11>;
55using uint12_t = fixed_uint_t<12>;
56using uint13_t = fixed_uint_t<13>;
57using uint14_t = fixed_uint_t<14>;
58using uint15_t = fixed_uint_t<15>;
59// native uint16_t
60using uint24_t = fixed_uint_t<24>;
61
62// signed fixed-bit sizes
63using int2_t = fixed_int_t<2>;
64using int3_t = fixed_int_t<3>;
65using int4_t = fixed_int_t<4>;
66using int5_t = fixed_int_t<5>;
67using int6_t = fixed_int_t<6>;
68using int7_t = fixed_int_t<7>;
69// native int8_t
70using int9_t = fixed_int_t<9>;
71using int10_t = fixed_int_t<10>;
72using int11_t = fixed_int_t<11>;
73using int12_t = fixed_int_t<12>;
74using int13_t = fixed_int_t<13>;
75using int14_t = fixed_int_t<14>;
76using int15_t = fixed_int_t<15>;
77// native int16_t
78using int24_t = fixed_int_t<24>;
79
80// bool is more efficient than a uint1_t
81using 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)>
85namespace types
86{
87namespace details
88{
89
Tim Leeb4905912022-06-18 02:51:13 +080090template <bitcount_t N>
Vernon Mauerye7329c72018-10-08 12:05:16 -070091struct Size
92{
Tim Leeb4905912022-06-18 02:51:13 +080093 static constexpr bitcount_t value = N;
Vernon Mauerye7329c72018-10-08 12:05:16 -070094};
95
Tim Leeb4905912022-06-18 02:51:13 +080096template <bitcount_t Bits>
Vernon Mauerye7329c72018-10-08 12:05:16 -070097constexpr auto getNrBits(const fixed_int_t<Bits>&) -> Size<Bits>;
Tim Leeb4905912022-06-18 02:51:13 +080098template <bitcount_t Bits>
Vernon Mauerye7329c72018-10-08 12:05:16 -070099constexpr auto getNrBits(const fixed_uint_t<Bits>&) -> Size<Bits>;
Tim Leeb4905912022-06-18 02:51:13 +0800100template <bitcount_t Bits>
Vernon Mauerye7329c72018-10-08 12:05:16 -0700101constexpr auto getNrBits(const std::bitset<Bits>&) -> Size<Bits>;
102
William A. Kennington III7a0e5df2021-05-19 13:31:29 -0700103template <typename U>
104using underlying_t =
105 typename std::conditional_t<std::is_enum_v<U>, std::underlying_type<U>,
106 std::enable_if<true, U>>::type;
107
Vernon Mauerye7329c72018-10-08 12:05:16 -0700108} // 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 */
119template <typename T>
120constexpr auto nrFixedBits =
121 decltype(details::getNrBits(std::declval<T>()))::value;
122
William A. Kennington III7a0e5df2021-05-19 13:31:29 -0700123/**
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 */
130template <typename R, typename T>
131inline 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
Vernon Mauerye7329c72018-10-08 12:05:16 -0700138} // namespace types