35 #ifndef VARIANT_IMPL_H 36 #define VARIANT_IMPL_H 38 #include <type_traits> 54 template <
typename BoolCondition>
59 struct is_integer : std::integral_constant<bool, std::is_integral<T>::value
60 && !std::is_same<T, bool>::value
61 && !std::is_same<T, char>::value>
64 template <
typename From,
typename To>
66 std::is_same<From, To>::value
67 && std::is_floating_point<To>::value >
71 template <
typename From,
typename To>
73 : std::integral_constant<bool, is_integer<From>::value
74 && is_integer<To>::value
75 && sizeof(From) <= sizeof(To)
76 && std::is_signed<From>::value == std::is_signed<To>::value>
79 template <typename From, typename To>
80 struct float_conversion
81 : std::integral_constant<bool, std::is_floating_point<From>::value
82 && std::is_floating_point<To>::value
83 && !std::is_same<From,To>::value >
86 template <typename From, typename To>
87 struct unsigned_to_smaller_conversion
88 : std::integral_constant<bool, is_integer<From>::value
89 && is_integer<To>::value
90 && (sizeof(From) > sizeof(To))
91 && !std::is_signed<From>::value
92 && !std::is_signed<To>::value >
95 template <
typename From,
typename To>
96 struct signed_to_smaller_conversion
97 : std::integral_constant<bool, is_integer<From>::value
98 && is_integer<To>::value
99 && (sizeof(From) > sizeof(To))
105 template <
typename From,
typename To>
106 struct signed_to_smaller_unsigned_conversion
107 : std::integral_constant<bool, is_integer<From>::value
108 && is_integer<To>::value
109 && sizeof(From) >= sizeof(To)
114 template <
typename From,
typename To>
115 struct signed_to_larger_unsigned_conversion
116 : std::integral_constant<bool, is_integer<From>::value
117 && is_integer<To>::value
118 && sizeof(From) < sizeof(To)
119 && std::is_signed<From>::value
120 && !std::is_signed<To>::value >
123 template <typename From, typename To>
124 struct unsigned_to_smaller_signed_conversion
125 : std::integral_constant<bool, is_integer<From>::value
126 && is_integer<To>::value
127 && (sizeof(From) >= sizeof(To))
128 && !std::is_signed<From>::value
129 && std::is_signed<To>::value >
132 template <
typename From,
typename To>
133 struct unsigned_to_larger_signed_conversion
134 : std::integral_constant<bool, is_integer<From>::value
135 && is_integer<To>::value
136 && sizeof(From) < sizeof(To)
137 && !std::is_signed<From>::value
138 && std::is_signed<To>::value >
141 template <typename From, typename To>
142 struct floating_to_signed_conversion
143 : std::integral_constant<bool, std::is_floating_point<From>::value
144 && is_integer<To>::value
145 && std::is_signed<To>::value >
148 template <typename From, typename To>
149 struct floating_to_unsigned_conversion
150 : std::integral_constant<bool, std::is_floating_point<From>::value
151 && is_integer<To>::value
152 && !std::is_signed<To>::value >
155 template <typename From, typename To>
156 struct integer_to_floating_conversion
157 : std::integral_constant<bool, is_integer<From>::value
158 && std::is_floating_point<To>::value >
161 template <typename From, typename To>
162 inline void checkUpperLimit(const From& from)
164 if ((sizeof(To) < sizeof(From)) &&
165 (from > static_cast<From>(std::numeric_limits<To>::max()))) {
166 throw RangeException("Value too large.");
168 else if (static_cast<To>(from) > std::numeric_limits<To>::max()) {
173 template <
typename From,
typename To>
174 inline void checkUpperLimitFloat(
const From& from)
176 if (from > std::numeric_limits<To>::max()){
181 template <
typename From,
typename To>
182 inline void checkLowerLimitFloat(
const From& from)
184 if (from < -std::numeric_limits<To>::max()){
189 template <
typename From,
typename To>
190 inline void checkLowerLimit(
const From& from)
192 if (from < std::numeric_limits<To>::min()){
197 template <
typename From,
typename To>
198 inline void checkTruncation(
const From& from)
200 if(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 )
220 target =
static_cast<DST
>( from);
223 template<
typename SRC,
typename DST,
225 inline void convert_impl(
const SRC& from, DST& target )
228 checkTruncation<SRC,DST>(from);
230 target =
static_cast<DST
>( from );
234 template<
typename SRC,
typename DST,
236 inline void convert_impl(
const SRC& from, DST& target )
238 checkUpperLimit<SRC,DST>(from);
239 target =
static_cast<DST
>(from);
242 template<
typename SRC,
typename DST,
244 inline void convert_impl(
const SRC& from, DST& target )
246 checkLowerLimit<SRC,DST>(from);
247 checkUpperLimit<SRC,DST>(from);
248 target =
static_cast<DST
>( from);
252 template<
typename SRC,
typename DST,
254 inline void convert_impl(
const SRC& from, DST& target )
257 throw RangeException(
"Value is negative and can't be converted to signed");
260 checkUpperLimit<SRC,DST>(from);
261 target =
static_cast<DST
>( from);
265 template<
typename SRC,
typename DST,
267 inline void convert_impl(
const SRC& from, DST& target )
270 throw RangeException(
"Value is negative and can't be converted to signed");
273 target =
static_cast<DST
>( from);
276 template<
typename SRC,
typename DST,
278 inline void convert_impl(
const SRC& from, DST& target )
280 target =
static_cast<DST
>( from);
283 template<
typename SRC,
typename DST,
285 inline void convert_impl(
const SRC& from, DST& target )
287 checkUpperLimit<SRC,DST>(from);
288 target =
static_cast<DST
>( from);
291 template<
typename SRC,
typename DST,
293 inline void convert_impl(
const SRC& from, DST& target )
295 checkLowerLimitFloat<SRC,DST>(from);
296 checkUpperLimitFloat<SRC,DST>(from);
298 if( from != static_cast<SRC>(static_cast<DST>( from))){
302 target =
static_cast<DST
>( from);
305 template<
typename SRC,
typename DST,
307 inline void convert_impl(
const SRC& from, DST& target )
310 throw RangeException(
"Value is negative and can't be converted to signed");
313 checkLowerLimitFloat<SRC,DST>(from);
315 if( from != static_cast<SRC>(static_cast<DST>( from))){
319 target =
static_cast<DST
>( from);
322 template<
typename SRC,
typename DST,
324 inline void convert_impl(
const SRC& from, DST& target )
326 checkTruncation<SRC,DST>(from);
327 target =
static_cast<DST
>( from);
Invoke< std::enable_if< BoolCondition::value > > EnableIf