File numeric.h
File List > common > numeric.h
Go to the documentation of this file
#pragma once
#include <cstdint>
#include <limits>
#include <type_traits>
namespace simtix {
template <typename T, typename U>
constexpr T saturate_cast(U value) noexcept {
if constexpr (std::is_signed_v<T> && std::is_unsigned_v<U>) {
// Handle unsigned-to-signed conversion
if (value > static_cast<U>(std::numeric_limits<T>::max())) {
return std::numeric_limits<T>::max();
}
} else if constexpr (std::is_unsigned_v<T> && std::is_signed_v<U>) {
// Handle signed-to-unsigned conversion
if (value < 0) {
return 0;
}
} else {
// U and T have the same signedness
if (value > static_cast<U>(std::numeric_limits<T>::max())) {
return std::numeric_limits<T>::max();
} else if (value < static_cast<U>(std::numeric_limits<T>::min())) {
return std::numeric_limits<T>::min();
}
}
// Perform the actual cast
return static_cast<T>(value);
}
template <typename T>
uint32_t bit_width(T value) {
return std::numeric_limits<T>::digits - __builtin_clz(value);
}
} // namespace simtix