Skip to content

No common_type between CNL types #1053

Description

@mpusz

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions