10#ifndef M5_UTILITY_CONVERSION_HPP
11#define M5_UTILITY_CONVERSION_HPP
26constexpr uint64_t low_bits_mask(
const size_t bits)
28 return (bits >= 64) ? ~uint64_t{0} : ((uint64_t{1} << bits) - 1);
37constexpr typename std::make_signed<T>::type to_signed_bits(
const T v,
const size_t bits)
39 using S =
typename std::make_signed<T>::type;
42 : ((
static_cast<uint64_t
>(v) & (uint64_t{1} << (bits - 1)))
43 ?
static_cast<S
>((
static_cast<uint64_t
>(v) & low_bits_mask(bits)) - (low_bits_mask(bits) + 1))
44 :
static_cast<S
>(
static_cast<uint64_t
>(v) & low_bits_mask(bits)));
61template <
size_t Bits,
typename T>
64 static_assert(std::is_integral<T>::value && std::is_unsigned<T>::value,
"T must be an unsigned integer");
65 static_assert(Bits <=
sizeof(T) * 8,
"Bits must be less than or equal to the number of bits in T");
67 return detail::to_signed_bits(v, Bits);
84constexpr auto unsigned_to_signed(
const T v,
const size_t bits) ->
typename std::make_signed<T>::type
86 static_assert(std::is_integral<T>::value && std::is_unsigned<T>::value,
"T must be an unsigned integer");
88 return detail::to_signed_bits(v, bits);
105template <
typename To,
typename From>
108 static_assert(std::is_integral<To>::value && std::is_unsigned<To>::value,
"To must be an unsigned integer");
109 static_assert(std::is_integral<From>::value && std::is_unsigned<From>::value,
"From must be an unsigned integer");
111 return static_cast<To
>(
static_cast<uintmax_t
>(v) >
static_cast<uintmax_t
>(std::numeric_limits<To>::max())
112 ? std::numeric_limits<To>::max()
constexpr To saturate_cast(const From v)
Narrows an unsigned integer, saturating at the maximum of the destination.
Definition conversion.hpp:106
constexpr auto unsigned_to_signed(const T v) -> typename std::make_signed< T >::type
Convert an unsigned integer of any maximum number of bits to a signed integer.
Definition conversion.hpp:62
Top level namespace of M5.
Definition base64.cpp:39