29 #ifndef PIRANHA_SAFE_CAST_HPP 30 #define PIRANHA_SAFE_CAST_HPP 32 #include <boost/numeric/conversion/cast.hpp> 36 #include <type_traits> 39 #include <piranha/detail/demangle.hpp> 54 using std::invalid_argument::invalid_argument;
62 template <
typename To,
typename From,
typename =
void>
67 = enable_if_t<conjunction<std::is_same<To, T>, std::is_same<From, T>, std::is_copy_constructible<T>>::value,
84 template <
typename T, enabler<T> = 0>
94 template <
typename To,
typename From>
95 using sc_int_int_enabler = enable_if_t<conjunction<std::is_integral<To>, std::is_integral<From>>::value>;
102 template <
typename To,
typename From>
118 return boost::numeric_cast<To>(f);
121 +
" cannot be converted to the type '" + detail::demangle<To>()
122 +
"', as the conversion cannot preserve the original value");
127 inline namespace impl
130 template <
typename To,
typename From>
131 using sc_float_to_int_enabler = enable_if_t<conjunction<std::is_integral<To>, std::is_floating_point<From>>::value>;
139 template <
typename To,
typename From>
156 if (unlikely(!std::isfinite(f))) {
158 +
" cannot be converted to the integral type '" 159 + detail::demangle<To>() +
"'");
161 if (std::trunc(f) != f) {
163 + std::to_string(f) +
" cannot be converted to the integral type '" 164 + detail::demangle<To>()
165 +
"', as the conversion cannot preserve the original value");
168 return boost::numeric_cast<To>(f);
171 +
" cannot be converted to the integral type '" 172 + detail::demangle<To>()
173 +
"', as the conversion cannot preserve the original value");
178 inline namespace impl
181 template <
typename To,
typename From>
182 using safe_cast_t_ = decltype(safe_cast_impl<uncvref_t<To>, From>{}(std::declval<const From &>()));
184 template <
typename To,
typename From>
186 = enable_if_t<conjunction<std::is_same<safe_cast_t_<To, From>, uncvref_t<To>>, is_returnable<uncvref_t<To>>>::value,
218 template <
typename To,
typename From>
219 inline safe_cast_type<To, From>
safe_cast(
const From &x)
224 inline namespace impl
227 template <
typename To,
typename From>
228 using safe_cast_t = decltype(safe_cast<To>(std::declval<From>()));
236 template <
typename To,
typename From>
239 static const bool implementation_defined = is_detected<safe_cast_t, To, From>::value;
243 static const bool value = implementation_defined;
247 template <
typename To,
typename From>
To operator()(const From &f) const
Call operator.
To operator()(const From &f) const
Call operator.
#define piranha_throw(exception_type,...)
Exception-throwing macro.
Default implementation of piranha::safe_cast().
To operator()(const T &f) const
Call operator.
static const bool value
Value of the type trait.
Type trait to detect piranha::safe_cast().
Exception to signal failure in piranha::safe_cast().
safe_cast_type< To, From > safe_cast(const From &x)
Safe cast.