35 #ifndef VARIANT_IMPL_H 36 #define VARIANT_IMPL_H 38 #include <type_traits> 53 template <
typename BoolCondition>
58 struct is_integer : std::integral_constant<bool, std::is_integral<T>::value
59 && !std::is_same<T, bool>::value
60 && !std::is_same<T, char>::value>
63 template <
typename From,
typename To>
65 std::is_same<From, To>::value
66 && std::is_floating_point<To>::value >
70 template <
typename From,
typename To>
72 : std::integral_constant<bool, is_integer<From>::value
73 && is_integer<To>::value
74 && sizeof(From) <= sizeof(To)
75 && std::is_signed<From>::value == std::is_signed<To>::value>
78 template <typename From, typename To>
79 struct float_conversion
80 : std::integral_constant<bool, std::is_floating_point<From>::value
81 && std::is_floating_point<To>::value
82 && !std::is_same<From,To>::value >
85 template <typename From, typename To>
86 struct unsigned_to_smaller_conversion
87 : std::integral_constant<bool, is_integer<From>::value
88 && is_integer<To>::value
89 && (sizeof(From) > sizeof(To))
90 && !std::is_signed<From>::value
91 && !std::is_signed<To>::value >
94 template <
typename From,
typename To>
95 struct signed_to_smaller_conversion
96 : std::integral_constant<bool, is_integer<From>::value
97 && is_integer<To>::value
98 && (sizeof(From) > sizeof(To))
104 template <
typename From,
typename To>
105 struct signed_to_smaller_unsigned_conversion
106 : std::integral_constant<bool, is_integer<From>::value
107 && is_integer<To>::value
108 && sizeof(From) >= sizeof(To)
110 && !std::is_signed<To>
::value >
113 template <
typename From,
typename To>
114 struct signed_to_larger_unsigned_conversion
115 : std::integral_constant<bool, is_integer<From>::value
116 && is_integer<To>::value
117 && sizeof(From) < sizeof(To)
118 && std::is_signed<From>::value
119 && !std::is_signed<To>::value >
122 template <typename From, typename To>
123 struct unsigned_to_smaller_signed_conversion
124 : std::integral_constant<bool, is_integer<From>::value
125 && is_integer<To>::value
126 && (sizeof(From) >= sizeof(To))
127 && !std::is_signed<From>::value
128 && std::is_signed<To>::value >
131 template <
typename From,
typename To>
132 struct unsigned_to_larger_signed_conversion
133 : std::integral_constant<bool, is_integer<From>::value
134 && is_integer<To>::value
135 && sizeof(From) < sizeof(To)
136 && !std::is_signed<From>::value
137 && std::is_signed<To>::value >
140 template <typename From, typename To>
141 struct floating_to_signed_conversion
142 : std::integral_constant<bool, std::is_floating_point<From>::value
143 && is_integer<To>::value
144 && std::is_signed<To>::value >
147 template <typename From, typename To>
148 struct floating_to_unsigned_conversion
149 : std::integral_constant<bool, std::is_floating_point<From>::value
150 && is_integer<To>::value
151 && !std::is_signed<To>::value >
154 template <typename From, typename To>
155 struct integer_to_floating_conversion
156 : std::integral_constant<bool, is_integer<From>::value
157 && std::is_floating_point<To>::value >
160 template <typename From, typename To>
161 inline void checkUpperLimit(const From& from)
163 if ((sizeof(To) < sizeof(From)) &&
164 (from > static_cast<From>(std::numeric_limits<To>::max()))) {
165 throw RangeException("Value too large.");
167 else if (static_cast<To>(from) > std::numeric_limits<To>::max()) {
172 template <
typename From,
typename To>
173 inline void checkUpperLimitFloat(
const From& from)
175 if (from > std::numeric_limits<To>::max()){
180 template <
typename From,
typename To>
181 inline void checkLowerLimitFloat(
const From& from)
183 if (from < -std::numeric_limits<To>::max()){
188 template <
typename From,
typename To>
189 inline void checkLowerLimit(
const From& from)
191 if (from < std::numeric_limits<To>::min()){
196 template <
typename From,
typename To>
197 inline void checkTruncation(
const From& from)
199 if (!std::isnan(static_cast<double>(from)) && from != static_cast<From>(static_cast<To>(from)))
208 template<
typename SRC,
typename DST,
210 inline void convert_impl(
const SRC& from, DST& target )
216 template<
typename SRC,
typename DST,
218 inline void convert_impl(
const SRC& from, DST& target )
221 target =
static_cast<DST
>( from);
224 template<
typename SRC,
typename DST,
226 inline void convert_impl(
const SRC& from, DST& target )
230 target =
static_cast<DST
>( from );
234 template<
typename SRC,
typename DST,
236 inline void convert_impl(
const SRC& from, DST& target )
240 checkUpperLimit<SRC,DST>(from);
241 target =
static_cast<DST
>( from);
244 template<
typename SRC,
typename DST,
246 inline void convert_impl(
const SRC& from, DST& target )
249 checkLowerLimit<SRC,DST>(from);
250 checkUpperLimit<SRC,DST>(from);
251 target =
static_cast<DST
>( from);
255 template<
typename SRC,
typename DST,
257 inline void convert_impl(
const SRC& from, DST& target )
261 throw RangeException(
"Value is negative and can't be converted to signed");
263 checkUpperLimit<SRC,DST>(from);
265 target =
static_cast<DST
>( from);
269 template<
typename SRC,
typename DST,
271 inline void convert_impl(
const SRC& from, DST& target )
276 throw RangeException(
"Value is negative and can't be converted to signed");
278 target =
static_cast<DST
>( from);
281 template<
typename SRC,
typename DST,
283 inline void convert_impl(
const SRC& from, DST& target )
286 target =
static_cast<DST
>( from);
289 template<
typename SRC,
typename DST,
291 inline void convert_impl(
const SRC& from, DST& target )
295 checkUpperLimit<SRC,DST>(from);
296 target =
static_cast<DST
>( from);
299 template<
typename SRC,
typename DST,
301 inline void convert_impl(
const SRC& from, DST& target )
305 checkLowerLimitFloat<SRC,DST>(from);
306 checkLowerLimitFloat<SRC,DST>(from);
308 if( from != static_cast<SRC>(static_cast<DST>( from)))
311 target =
static_cast<DST
>( from);
314 template<
typename SRC,
typename DST,
316 inline void convert_impl(
const SRC& from, DST& target )
320 throw RangeException(
"Value is negative and can't be converted to signed");
322 checkLowerLimitFloat<SRC,DST>(from);
324 if( from != static_cast<SRC>(static_cast<DST>( from)))
327 target =
static_cast<DST
>( from);
330 template<
typename SRC,
typename DST,
332 inline void convert_impl(
const SRC& from, DST& target )
336 checkTruncation<SRC,DST>(from);
337 target =
static_cast<DST
>( from);
Invoke< std::enable_if< BoolCondition::value > > EnableIf