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