Date: Mon, 27 Nov 2023 16:33:24 -0500

On 11/24/23 1:13 PM, Paul Caprioli via Std-Proposals wrote:

> Thanks, Tom.

>

> I'd like to offer an observation regarding P2098. Since the template specializations of std::complex<T> were removed in C++23, std::complex<float> instantiates the primary template. So it may not be immediately obvious that the following is true: std::is_specialization_of_v<std::complex<float>, std::complex>

>

> Also, considering the following,

>

> struct MyFloat { uint64_t data[8]; };

> using T = std::numeric_limits<MyFloat>;

> static_assert(not T::is_specialized);

> static_assert(std::is_specialization_of_v<T, std::numeric_limits>);

>

> perhaps teachability and the readability of user code could be improved by some other name. One thought that comes to mind is

>

> std::is_instance_of_v<T, std::numeric_limits>

>

In my opinion, std::is_specialization_of_v is the right name. I am aware

that there are programmers that are not familiar with some of the

terminology and are unaware that a (explicit or implicit) template

instantiation and an explicit specialization both produce a

specialization of the primary template. But I don't find that a

motivating reason to add additional terminology. The terminology that we

have now is consistent and teachable (but perhaps not taught enough).

In general, I don't think we should expose whether a template

specialization was produced from an instantiation of a (partial)

template or an explicit specialization. The distinction should not

matter for users of these types. If std::numeric_limits were being

designed today, I don't think it would have a is_specialized data

member. I think we would instead specify an incomplete primary class

template and expect SFINAE or concepts to be used to determine when an

explicit specialization is needed.

Tom.

> Regards,

> Paul

>

>

> -----Original message-----

> From: Tom Honermann <tom_at_[hidden]>

> Sent: Monday, November 20 2023, 9:21 am

> To: std-proposals_at_[hidden] <std-proposals_at_[hidden]>

> Cc: Paul Caprioli <paul_at_[hidden]>

> Subject: Re: [std-proposals] Complex type traits

>

> Previous proposals have explored such traits. See:

>

> P2078 <https://wg21.link/p2078>: Add new traits

> type std::is_complex<T>

> P2098 <https://wg21.link/p2098>: Proposing std::is_specialization_of

>

> Progress on P2078 is blocked on further work by its author.

>

> Progress on P2098 is blocked on a proposal that doesn't have the

> limitations described in the paper. I believe the adoption of P2989 (A Simple Approach to

> Universal Template Parameters) <https://wg21.link/p2989> would suffice to enable std::is_specialization_of to be

> implemented as a library feature without such limitations. P2989

> is making its way through the committee process now (expected to

> be reviewed in EWG pending a new revision by its authors).

>

> Tom.

>

> On 11/19/23 9:34 PM, Paul Caprioli via

> Std-Proposals wrote:

>

> I'd like to float the idea of complex type traits, specifically `add_complex_t<T>`, `remove_complex_t<T>`, and the boolean `is_complex_v<T>`.

>

> Since a pointer to an element of an array of `std::complex<T>` can be reinterpreted as a pointer to `T` (with the real-valued array having twice as many elements), some codes use the former and others the latter. So, templated code in libraries and suchlike may want to work with either.

>

> My actual use case is FFTs, which can take real or complex arrays and real-valued scaling factors. The functions taking complex-valued arrays can accept `T*`. The scaling factor must be real, not complex. If you are curious about this in particular, my web page is https://hpkfft.com <https://hpkfft.com> and the type traits are here: https://hpkfft.com/hpk/complex_type_traits.html <https://hpkfft.com/hpk/complex_type_traits.html>

>

> Are these type traits generally useful enough for std? This question has nothing to do with FFTs.

>

> A motivating example might by `axpy()`, which multiplies the real-valued scalar `a` to each element of the array `x` and adds this to the array `y`. The array elements can be, say, `float` or `std::complex<float>`, but the scalar `a` has to be `float`. Note that the arrays can be arrays of real values or arrays of complex values, and if complex values, the type can still be `float*` with the understanding that the real and imaginary parts are interleaved. The same implementation works. If `a` were complex, then a different implementation would be needed.

>

> Regards,

> Paul

>

>

> Thanks, Tom.

>

> I'd like to offer an observation regarding P2098. Since the template specializations of std::complex<T> were removed in C++23, std::complex<float> instantiates the primary template. So it may not be immediately obvious that the following is true: std::is_specialization_of_v<std::complex<float>, std::complex>

>

> Also, considering the following,

>

> struct MyFloat { uint64_t data[8]; };

> using T = std::numeric_limits<MyFloat>;

> static_assert(not T::is_specialized);

> static_assert(std::is_specialization_of_v<T, std::numeric_limits>);

>

> perhaps teachability and the readability of user code could be improved by some other name. One thought that comes to mind is

>

> std::is_instance_of_v<T, std::numeric_limits>

>

In my opinion, std::is_specialization_of_v is the right name. I am aware

that there are programmers that are not familiar with some of the

terminology and are unaware that a (explicit or implicit) template

instantiation and an explicit specialization both produce a

specialization of the primary template. But I don't find that a

motivating reason to add additional terminology. The terminology that we

have now is consistent and teachable (but perhaps not taught enough).

In general, I don't think we should expose whether a template

specialization was produced from an instantiation of a (partial)

template or an explicit specialization. The distinction should not

matter for users of these types. If std::numeric_limits were being

designed today, I don't think it would have a is_specialized data

member. I think we would instead specify an incomplete primary class

template and expect SFINAE or concepts to be used to determine when an

explicit specialization is needed.

Tom.

> Regards,

> Paul

>

>

> -----Original message-----

> From: Tom Honermann <tom_at_[hidden]>

> Sent: Monday, November 20 2023, 9:21 am

> To: std-proposals_at_[hidden] <std-proposals_at_[hidden]>

> Cc: Paul Caprioli <paul_at_[hidden]>

> Subject: Re: [std-proposals] Complex type traits

>

> Previous proposals have explored such traits. See:

>

> P2078 <https://wg21.link/p2078>: Add new traits

> type std::is_complex<T>

> P2098 <https://wg21.link/p2098>: Proposing std::is_specialization_of

>

> Progress on P2078 is blocked on further work by its author.

>

> Progress on P2098 is blocked on a proposal that doesn't have the

> limitations described in the paper. I believe the adoption of P2989 (A Simple Approach to

> Universal Template Parameters) <https://wg21.link/p2989> would suffice to enable std::is_specialization_of to be

> implemented as a library feature without such limitations. P2989

> is making its way through the committee process now (expected to

> be reviewed in EWG pending a new revision by its authors).

>

> Tom.

>

> On 11/19/23 9:34 PM, Paul Caprioli via

> Std-Proposals wrote:

>

> I'd like to float the idea of complex type traits, specifically `add_complex_t<T>`, `remove_complex_t<T>`, and the boolean `is_complex_v<T>`.

>

> Since a pointer to an element of an array of `std::complex<T>` can be reinterpreted as a pointer to `T` (with the real-valued array having twice as many elements), some codes use the former and others the latter. So, templated code in libraries and suchlike may want to work with either.

>

> My actual use case is FFTs, which can take real or complex arrays and real-valued scaling factors. The functions taking complex-valued arrays can accept `T*`. The scaling factor must be real, not complex. If you are curious about this in particular, my web page is https://hpkfft.com <https://hpkfft.com> and the type traits are here: https://hpkfft.com/hpk/complex_type_traits.html <https://hpkfft.com/hpk/complex_type_traits.html>

>

> Are these type traits generally useful enough for std? This question has nothing to do with FFTs.

>

> A motivating example might by `axpy()`, which multiplies the real-valued scalar `a` to each element of the array `x` and adds this to the array `y`. The array elements can be, say, `float` or `std::complex<float>`, but the scalar `a` has to be `float`. Note that the arrays can be arrays of real values or arrays of complex values, and if complex values, the type can still be `float*` with the understanding that the real and imaginary parts are interleaved. The same implementation works. If `a` were complex, then a different implementation would be needed.

>

> Regards,

> Paul

>

>

Received on 2023-11-27 21:33:27