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