cast: tighten trunc_cast type restrictions
trunc_cast should be between float/int/uint or to types of lesser precision. also restrict to fundamental types until we actually test with arbitrary types.
This commit is contained in:
parent
d51cfe7a34
commit
0e29675ef5
26
cast.hpp
26
cast.hpp
@ -71,26 +71,36 @@ sign_cast (const U u)
|
||||
/// assert if the value cannot be cast loslessly from U to T, else return the
|
||||
/// converted value.Note: this is only a debug-time check and is compiled out
|
||||
/// in optimised builds.
|
||||
///
|
||||
/// relies on equality operators being present and behaving sanely. attempts
|
||||
/// to preserve NaN values.
|
||||
///
|
||||
/// allows the identity cast (if only to make cross-platform porting easier)
|
||||
template <
|
||||
typename T,
|
||||
typename U
|
||||
>
|
||||
std::enable_if_t<
|
||||
// either we're casting from real to integer
|
||||
!std::is_floating_point<T>::value && std::is_floating_point<U>::value
|
||||
// or we're reducing the size of the type
|
||||
|| sizeof (T) < sizeof (U),
|
||||
// only enabled for builtin types. there's no reason this couldn't be
|
||||
// extended, but we've only really tested on integers and floats.
|
||||
std::is_fundamental<T>::value && std::is_fundamental<U>::value && (
|
||||
// either we're casting between real and integer
|
||||
std::is_floating_point<T>::value != std::is_floating_point<U>::value
|
||||
// or we're reducing the size of the type
|
||||
|| sizeof (T) <= sizeof (U)
|
||||
),
|
||||
T
|
||||
>
|
||||
trunc_cast (U u)
|
||||
trunc_cast (const U &u)
|
||||
{
|
||||
auto t = static_cast<T> (u);
|
||||
|
||||
// assume testing round-trip error is the same as half-trip error. this
|
||||
// makes satisfying the type system (for the debug checks) a lot easier,
|
||||
// but seems like it might bite us later...
|
||||
// if we're not a NaN then check equality by casting U-to-T-to-U. we can't
|
||||
// explicitly check isnan because that call isn't valid for arbitrary
|
||||
// types and we'll cause a compile-time error.
|
||||
if (u == u)
|
||||
CHECK_EQ (static_cast<U> (t), u);
|
||||
// we must be a NaN. test that t is a NaN too by self-equality.
|
||||
else
|
||||
CHECK_NEQ (t, t);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user