-
Notifications
You must be signed in to change notification settings - Fork 4
/
safe_cast.hpp
32 lines (28 loc) · 1.32 KB
/
safe_cast.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <limits>
#include <stdexcept>
#include <type_traits>
#include <cassert>
template <typename To, typename From> // signed -> signed
inline typename std::enable_if<std::is_signed<To>::value && std::is_signed<From>::value, To>::type safe_cast(From value)
{
assert (value >= std::numeric_limits<To>::min() && value <= std::numeric_limits<To>::max());
return static_cast<To>(value);
}
template <typename To, typename From> // signed -> unsigned
inline typename std::enable_if<std::is_signed<To>::value && std::is_unsigned<From>::value, To>::type safe_cast(From value)
{
assert (value <= static_cast<typename std::make_unsigned<To>::type>(std::numeric_limits<To>::max()));
return static_cast<To>(value);
}
template <typename To, typename From> // unsigned -> signed
inline typename std::enable_if<std::is_unsigned<To>::value && std::is_signed<From>::value, To>::type safe_cast(From value)
{
assert (value >= 0 && static_cast<typename std::make_unsigned<From>::type>(value) <= std::numeric_limits<To>::max());
return static_cast<To>(value);
}
template <typename To, typename From> // unsigned -> unsigned
inline typename std::enable_if<std::is_unsigned<To>::value && std::is_unsigned<From>::value, To>::type safe_cast(From value)
{
assert (value <= std::numeric_limits<To>::max());
return static_cast<To>(value);
}