M5Utility 0.3.0 git rev:41a629c
Loading...
Searching...
No Matches
conversion.hpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD
3 *
4 * SPDX-License-Identifier: MIT
5 */
10#ifndef M5_UTILITY_CONVERSION_HPP
11#define M5_UTILITY_CONVERSION_HPP
12
13#include <type_traits>
14#include <limits>
15#include <cstdint>
16#include <cstdint>
17#include <cstddef>
18
19namespace m5 {
20namespace utility {
21
23namespace detail {
24
26constexpr uint64_t low_bits_mask(const size_t bits)
27{
28 return (bits >= 64) ? ~uint64_t{0} : ((uint64_t{1} << bits) - 1);
29}
30
36template <typename T>
37constexpr typename std::make_signed<T>::type to_signed_bits(const T v, const size_t bits)
38{
39 using S = typename std::make_signed<T>::type;
40 return (bits == 0)
41 ? S{0}
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)));
45}
46
47} // namespace detail
49
61template <size_t Bits, typename T>
62constexpr auto unsigned_to_signed(const T v) -> typename std::make_signed<T>::type
63{
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");
66
67 return detail::to_signed_bits(v, Bits);
68}
69
83template <typename T>
84constexpr auto unsigned_to_signed(const T v, const size_t bits) -> typename std::make_signed<T>::type
85{
86 static_assert(std::is_integral<T>::value && std::is_unsigned<T>::value, "T must be an unsigned integer");
87
88 return detail::to_signed_bits(v, bits);
89}
90
105template <typename To, typename From>
106constexpr To saturate_cast(const From v)
107{
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");
110
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()
113 : v);
114}
115
116} // namespace utility
117} // namespace m5
118#endif
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
For utilities.