Add sign_cast functions

These safely cast between signed and unsigned numeric quantities,
aborting if the result cannot be safely converted (as opposed to size
expanding or throwing).
This commit is contained in:
Danny Robson 2011-06-15 22:38:58 +10:00
parent 16e4cde82d
commit 4891c6af0e

View File

@ -3,6 +3,7 @@
#include <cstdint> #include <cstdint>
#include <string> #include <string>
#include <limits>
template <int BITS> template <int BITS>
struct bits_type; struct bits_type;
@ -53,4 +54,43 @@ template <typename T>
std::string type_to_string (void); std::string type_to_string (void);
template <typename T>
struct sign_types;
template <> struct sign_types <signed int> {
typedef signed int with_sign;
typedef unsigned int without_sign;
};
template <> struct sign_types <unsigned int> {
typedef signed int with_sign;
typedef unsigned int without_sign;
};
/// Safely cast a numeric type to its signed comparison, aborting if the
/// result is not representable.
template <typename T>
typename sign_types<T>::with_sign
sign_cast (const typename sign_types<T>::without_sign v)
{
check_hard (v <= std::numeric_limits<typename sign_types<T>::without_sign>::max () >> 1);
return static_cast <typename sign_types<T>::with_sign> (v);
}
/// Safely cast a numeric type to its unsigned comparison, aborting if the
/// result is not representable.
template <typename T>
typename sign_types<T>::without_sign
sign_cast (const typename sign_types<T>::with_sign v)
{
check_hard (v >= 0);
return static_cast <typename sign_types<T>::without_sign> (v);
}
#endif // __TYPES_HPP #endif // __TYPES_HPP