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))
99 && std::is_signed<From>::value
100 && std::is_signed<To>::value >
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)
109 && std::is_signed<From>::value
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( from != static_cast<From>(static_cast<To>( from))){
207 template<
typename SRC,
typename DST,
209 inline void convert_impl(
const SRC& from, DST& target )
215 template<
typename SRC,
typename DST,
217 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);
229 target =
static_cast<DST
>( from );
233 template<
typename SRC,
typename DST,
235 inline void convert_impl(
const SRC& from, DST& target )
239 checkUpperLimit<SRC,DST>(from);
240 target =
static_cast<DST
>( from);
243 template<
typename SRC,
typename DST,
245 inline void convert_impl(
const SRC& from, DST& target )
248 checkLowerLimit<SRC,DST>(from);
249 checkUpperLimit<SRC,DST>(from);
250 target =
static_cast<DST
>( from);
254 template<
typename SRC,
typename DST,
256 inline void convert_impl(
const SRC& from, DST& target )
260 throw RangeException(
"Value is negative and can't be converted to signed");
262 checkUpperLimit<SRC,DST>(from);
264 target =
static_cast<DST
>( from);
268 template<
typename SRC,
typename DST,
270 inline void convert_impl(
const SRC& from, DST& target )
275 throw RangeException(
"Value is negative and can't be converted to signed");
277 target =
static_cast<DST
>( from);
280 template<
typename SRC,
typename DST,
282 inline void convert_impl(
const SRC& from, DST& target )
285 target =
static_cast<DST
>( from);
288 template<
typename SRC,
typename DST,
290 inline void convert_impl(
const SRC& from, DST& target )
294 checkUpperLimit<SRC,DST>(from);
295 target =
static_cast<DST
>( from);
298 template<
typename SRC,
typename DST,
300 inline void convert_impl(
const SRC& from, DST& target )
304 checkLowerLimitFloat<SRC,DST>(from);
305 checkLowerLimitFloat<SRC,DST>(from);
307 if( from != static_cast<SRC>(static_cast<DST>( from)))
310 target =
static_cast<DST
>( from);
313 template<
typename SRC,
typename DST,
315 inline void convert_impl(
const SRC& from, DST& target )
319 throw RangeException(
"Value is negative and can't be converted to signed");
321 checkLowerLimitFloat<SRC,DST>(from);
323 if( from != static_cast<SRC>(static_cast<DST>( from)))
326 target =
static_cast<DST
>( from);
329 template<
typename SRC,
typename DST,
331 inline void convert_impl(
const SRC& from, DST& target )
335 checkTruncation<SRC,DST>(from);
336 target =
static_cast<DST
>( from);
Invoke< std::enable_if< BoolCondition::value > > EnableIf