What are you trying to do?
int s behave as the following:
int16_t i16 = 42;
static_assert(std::is_same_v<decltype(-i16), int>);
static_assert(std::is_same_v<std::common_type_t<decltype(i16), decltype(-i16)>, int>);
Negation of the short type results in an integral promotion to int. Both of those types have common types.
When I try to do the same for CNL types, the integral promotion happens, but the results do not have a common type with the source type:
using cnl16_t = cnl::scaled_integer<int16_t, cnl::power<-2>>;
using cnlint_t = cnl::scaled_integer<int, cnl::power<-2>>;
cnl16_t cnl16 = 42;
static_assert(std::is_same_v<decltype(-cnl16), cnlint_t>);
// static_assert(std::is_same_v<std::common_type_t<decltype(cnl16), decltype(-cnl16)>, cnlint_t>); // does not compile - no common type
Repro here: https://godbolt.org/z/W8xrbncch
Is this behavior intentional?
Why does it matter?
It was discovered by the mp-units representation type constraints that, as of today, require the following:
template<typename T, typename S>
concept ScalableWith = requires(const T v, const S s) {
{ v * s / s } -> std::common_with<T>;
{ s * v / s } -> std::common_with<T>;
{ v / s * s } -> std::common_with<T>;
};
template<typename T>
concept Addable = requires(const T a, const T b) {
{ -a } -> std::common_with<T>;
{ a + b } -> std::common_with<T>;
{ a - b } -> std::common_with<T>;
};
template<typename T>
concept WeaklyRegular = std::copyable<T> && std::equality_comparable<T>;
template<typename T>
concept NumberLike = Addable<T> && WeaklyRegular<T>;
template<typename T>
concept BaseScalar = NumberLike<T> && ScalableWith<T, T>;
From the above { -a } -> std::common_with<T>; makes CNL types not satisfy the current mp-units requirements.
I am not claiming that the above constraints are ideal, and feedback is welcome. Anyway, other libraries may do similar things, and they will face the same issues.
What are you trying to do?
ints behave as the following:Negation of the short type results in an integral promotion to
int. Both of those types have common types.When I try to do the same for CNL types, the integral promotion happens, but the results do not have a common type with the source type:
Repro here: https://godbolt.org/z/W8xrbncch
Is this behavior intentional?
Why does it matter?
It was discovered by the mp-units representation type constraints that, as of today, require the following:
From the above
{ -a } -> std::common_with<T>;makes CNL types not satisfy the current mp-units requirements.I am not claiming that the above constraints are ideal, and feedback is welcome. Anyway, other libraries may do similar things, and they will face the same issues.