15 #include <type_traits>
27 template <
typename BoolCondition>
28 using EnableIf =
typename std::enable_if<BoolCondition::value, void>::type;
57 template <
typename T1,
typename T2>
63 template <
typename From,
typename To>
66 if(from >
static_cast<From
>(std::numeric_limits<To>::max()))
68 throw std::runtime_error(
"Value outside the max numerical limit.");
72 template <
typename From,
typename To>
77 if(from != 0 && from != 1)
79 throw std::runtime_error(
"Implicit casting to bool is not allowed");
82 else if(from < std::numeric_limits<To>::min())
84 throw std::runtime_error(
"Value outside the lovest numerical limit.");
88 template <
typename From,
typename To>
91 if(from !=
static_cast<From
>(
static_cast<To
>(from)))
93 throw std::runtime_error(
"Floating point truncated");
99 template <
typename SRC,
typename DST>
102 static_assert(is_convertible_type<SRC>() && is_convertible_type<DST>(),
"Not "
105 constexpr
bool both_integers = is_integer<SRC>() && is_integer<DST>();
107 if constexpr(is_signed<SRC>() && !is_signed<DST>())
111 throw std::runtime_error(
"Value is negative and can't be converted to unsigned");
117 if constexpr(is_same<SRC, DST>() || (is_same<SRC, float>() && is_same<DST, double>()))
120 target =
static_cast<DST
>(source);
122 else if constexpr(both_integers)
124 if constexpr(
sizeof(SRC) ==
sizeof(DST) && !is_signed<SRC>() && is_signed<DST>())
126 checkUpperLimit<SRC, DST>(source);
129 else if constexpr(
sizeof(SRC) >
sizeof(DST))
131 if constexpr(is_signed<SRC>())
133 checkLowerLimit<SRC, DST>(source);
135 checkUpperLimit<SRC, DST>(source);
137 target =
static_cast<DST
>(source);
140 else if constexpr(is_convertible_to_bool<SRC>() && is_same<DST, bool>())
142 target =
static_cast<DST
>(source);
153 checkTruncation<SRC, DST>(source);
155 target =
static_cast<DST
>(source);