1 #ifndef CONVERT_IMPL_HPP 2 #define CONVERT_IMPL_HPP 12 template <
typename BoolCondition>
13 using EnableIf =
typename std::enable_if<BoolCondition::value, void>::type;
17 : std::integral_constant<bool, std::is_integral<T>::value && !std::is_same<T, bool>::value &&
18 !std::is_same<T, char>::value>
22 template <
typename From,
typename To>
24 : std::integral_constant<bool, std::is_same<From, To>::value && std::is_floating_point<To>::value>
28 template <
typename From,
typename To>
30 : std::integral_constant<bool, is_integer<From>::value && is_integer<To>::value &&
31 sizeof(From) < sizeof(To) &&
32 std::is_signed<From>::value == std::is_signed<To>::value>
37 struct is_convertible_type
38 : std::integral_constant<bool, std::is_integral<T>::value || std::is_floating_point<T>::value ||
39 std::is_same<T, bool>::value || std::is_same<T, char>::value ||
40 std::is_same<T, std::string>::value ||
41 std::is_same<T, SimpleString>::value || std::is_enum<T>::value>
45 template <typename From, typename To>
46 struct float_conversion : std::integral_constant<bool, std::is_floating_point<From>::value &&
47 std::is_floating_point<To>::value &&
48 !std::is_same<From, To>::value>
52 template <typename From, typename To>
53 struct unsigned_to_smaller_conversion
54 : std::integral_constant<bool, is_integer<From>::value && is_integer<To>::value &&
55 (sizeof(From) > sizeof(To)) && !std::is_signed<From>::value &&
56 !std::is_signed<To>::value>
60 template <
typename From,
typename To>
61 struct signed_to_smaller_conversion
62 : std::integral_constant<bool, is_integer<From>::value && is_integer<To>::value &&
63 (sizeof(From) > sizeof(To)) && std::is_signed<From>::value &&
64 std::is_signed<To>::value>
69 template <
typename From,
typename To>
70 struct signed_to_smaller_unsigned_conversion
71 : std::integral_constant<bool, is_integer<From>::value && is_integer<To>::value &&
72 sizeof(From) >= sizeof(To) && std::is_signed<From>::value &&
73 !std::is_signed<To>::value>
77 template <
typename From,
typename To>
78 struct signed_to_larger_unsigned_conversion
79 : std::integral_constant<bool, is_integer<From>::value && is_integer<To>::value &&
80 sizeof(From) < sizeof(To) && std::is_signed<From>::value &&
81 !std::is_signed<To>::value>
85 template <typename From, typename To>
86 struct unsigned_to_smaller_signed_conversion
87 : std::integral_constant<bool, is_integer<From>::value && is_integer<To>::value &&
88 (sizeof(From) >= sizeof(To)) && !std::is_signed<From>::value &&
89 std::is_signed<To>::value>
93 template <
typename From,
typename To>
94 struct unsigned_to_larger_signed_conversion
95 : std::integral_constant<bool, is_integer<From>::value && is_integer<To>::value &&
96 sizeof(From) < sizeof(To) && !std::is_signed<From>::value &&
97 std::is_signed<To>::value>
101 template <typename From, typename To>
102 struct floating_to_signed_conversion
103 : std::integral_constant<bool, std::is_floating_point<From>::value && is_integer<To>::value &&
104 std::is_signed<To>::value>
108 template <typename From, typename To>
109 struct floating_to_unsigned_conversion
110 : std::integral_constant<bool, std::is_floating_point<From>::value && is_integer<To>::value &&
111 !std::is_signed<To>::value>
115 template <typename From, typename To>
116 struct integer_to_floating_conversion
117 : std::integral_constant<bool, is_integer<From>::value && std::is_floating_point<To>::value>
121 template <typename From, typename To>
122 inline void checkUpperLimit(const From& from)
124 if ((sizeof(To) < sizeof(From)) && (from > static_cast<From>(std::numeric_limits<To>::max())))
126 throw std::runtime_error("Value too large.");
128 else if (static_cast<To>(from) > std::numeric_limits<To>::max())
130 throw std::runtime_error(
"Value too large.");
134 template <
typename From,
typename To>
135 inline void checkUpperLimitFloat(
const From& from)
137 if (from > std::numeric_limits<To>::max())
139 throw std::runtime_error(
"Value too large.");
143 template <
typename From,
typename To>
144 inline void checkLowerLimitFloat(
const From& from)
146 if (from < -std::numeric_limits<To>::max())
148 throw std::runtime_error(
"Value too small.");
152 template <
typename From,
typename To>
153 inline void checkLowerLimit(
const From& from)
155 if (from < std::numeric_limits<To>::min())
157 throw std::runtime_error(
"Value too small.");
161 template <
typename From,
typename To>
162 inline void checkTruncation(
const From& from)
164 if (from != static_cast<From>(static_cast<To>(from)))
166 throw std::runtime_error(
"Floating point truncated");
172 template <
typename SRC,
typename DST>
173 inline typename std::enable_if<!is_convertible_type<DST>::value,
void>::type
174 convertNumber(
const SRC&, DST&)
176 static_assert(is_convertible_type<DST>::value,
"Not convertible");
179 template <
typename SRC,
typename DST>
182 target = (from != 0);
185 template <
typename SRC,
typename DST>
191 template <
typename SRC,
typename DST>
194 target =
static_cast<DST
>(from);
197 template <
typename SRC,
typename DST>
200 checkTruncation<SRC, DST>(from);
201 target =
static_cast<DST
>(from);
204 template <
typename SRC,
typename DST>
208 checkUpperLimit<SRC, DST>(from);
209 target =
static_cast<DST
>(from);
212 template <
typename SRC,
typename DST>
215 checkLowerLimit<SRC, DST>(from);
216 checkUpperLimit<SRC, DST>(from);
217 target =
static_cast<DST
>(from);
220 template <
typename SRC,
typename DST>
226 throw std::runtime_error(
"Value is negative and can't be converted to signed");
229 checkUpperLimit<SRC, DST>(from);
230 target =
static_cast<DST
>(from);
233 template <
typename SRC,
typename DST>
239 throw std::runtime_error(
"Value is negative and can't be converted to signed");
242 target =
static_cast<DST
>(from);
245 template <
typename SRC,
typename DST>
249 target =
static_cast<DST
>(from);
252 template <
typename SRC,
typename DST>
256 checkUpperLimit<SRC, DST>(from);
257 target =
static_cast<DST
>(from);
260 template <
typename SRC,
typename DST>
263 checkLowerLimitFloat<SRC, DST>(from);
264 checkLowerLimitFloat<SRC, DST>(from);
266 if (from != static_cast<SRC>(static_cast<DST>(from)))
268 throw std::runtime_error(
"Floating point truncated");
271 target =
static_cast<DST
>(from);
274 template <
typename SRC,
typename DST>
280 throw std::runtime_error(
"Value is negative and can't be converted to signed");
283 checkLowerLimitFloat<SRC, DST>(from);
285 if (from != static_cast<SRC>(static_cast<DST>(from)))
287 throw std::runtime_error(
"Floating point truncated");
290 target =
static_cast<DST
>(from);
293 template <
typename SRC,
typename DST>
297 checkTruncation<SRC, DST>(from);
298 target =
static_cast<DST
>(from);
304 #endif // CONVERT_IMPL_HPP
typename std::enable_if< BoolCondition::value, void >::type EnableIf