Type relationship safe_arithmetic_conversion (original) (raw)

The safe_arithmetic_conversion type trait has the same syntax as std::is_constructible. It determines the behavior of safely_constructible for arithmetic types.

It is defined in terms of sign, arithmetic category and arithmetic rank of its arguments.

Valid Expressions

expression value
T, U any arithmetic types
safe_arithmetic_conversion<T, U>::value true if a variant for which T is one of the value types should be constructible from U.

Notes

Definition

The complete definition is given:

template <typename A, typename B> struct safe_arithmetic_conversion { static constexpr bool same_class = (mpl::classify_arithmetic::value == mpl::classify_arithmetic::value); static constexpr bool unsign_to_sign = !std::is_unsigned::value && std::is_unsigned::value; static constexpr bool narrowing = (mpl::arithmetic_rank::value < mpl::arithmetic_rank::value);

static constexpr bool value = same_class && !unsign_to_sign && !narrowing; };

template struct safe_arithmetic_conversion<A, char> { static constexpr bool value = safe_arithmetic_conversion<A, signed char>::value && safe_arithmetic_conversion<A, unsigned char>::value; };

template struct safe_arithmetic_conversion<char, B> { static constexpr bool value = safe_arithmetic_conversion<signed char, B>::value && safe_arithmetic_conversion<unsigned char, B>::value; };

template <> struct safe_arithmetic_conversion<char, char> : std::true_type {};

The type char requires special treatment, because it is implementation-defined if it is signed or unsigned. Since we'd like to eliminate implementation-specific behavior, an arithmetic conversion involvingchar is permitted only when it would be permitted for both signed char and unsigned char.

[Note] Note
You are welcome to specialize this trait to modify the behavior of strict_variant, but it might not always be the simplest way. Consider specializing arithmetic_rank and/or classify_arithmetic, or safely_constructible, instead.