Closed hfinkel closed 5 years ago
I'm going to close this bug. We're compliant here - the results are "unspecified".
If we want to add support for custom types to our complex implementation, that's fine. But this bug isn't going to help is.
I'm leaning towards option #2 - basically, static_assert.
I think that's better than "sorta working" or "working for some things and not others".
The other choice would be your option #5 - make everything work - and for that I would be happy to review patches.
Do you happen to know if there's any history here of the committee discussing specifically allowing other types?
I'm sure there was such a discussion; otherwise the paragraph that I quoted would not be there in the standard.
However, the first sentence of that paragraph has been unchanged in the standard since 1998; so any such discussion was a long time ago.
Indeed ;)
In any case, any opinion on how to move forward. All things considered, I think that my option 4 is probably the best, and I'd like to propose updating the standard to allow the same. There are good use cases for this, and I expect that all, or almost all, implementations already work in this regard.
FWIW, boost_1_62_0/libs/numeric/ublas/benchmarks/bench4/bench4.cpp has:
74 #ifdef USE_BOOST_COMPLEX
75
76 template struct peak<boost::complex<boost::numeric::interval
which does represent a good use case.
Do you happen to know if there's any history here of the committee discussing specifically allowing other types?
I'm sure there was such a discussion; otherwise the paragraph that I quoted would not be there in the standard.
However, the first sentence of that paragraph has been unchanged in the standard since 1998; so any such discussion was a long time ago.
This also brings up another issue: Does the standard say anything about what is required of a type T for std::complex
to work. [complex.numbers]/2 says: The effect of instantiating the template complex for any type other than float, double, or long double is unspecified. The specializations complex
, complex , and complex are literal types (3.9).
What do you think we should do; there seem to be many options:
Do you happen to know if there's any history here of the committee discussing specifically allowing other types?
This also brings up another issue: Does the standard say anything about what is required of a type T for std::complex
to work.
[complex.numbers]/2 says:
The effect of instantiating the template complex for any type other than float, double, or long double is unspecified. The specializations complex
This also brings up another issue: Does the standard say anything about what is required of a type T for std::complex
Extended Description
In https://reviews.llvm.org/D18639, Eric asked if we supporting using std::complex with custom numeric types. The answer is: mostly. I've attached the test case I started writing. This compiles with libstdc++, and in fact, requires a lot less of the custom type than we do (e.g. we require fabs in addition to abs, scalbn, logb, and many other functions). With libc++, however, we do it one compilation error which looks like a problem with libc++ itself:
include/c++/v1/complex:1321:39: error: no matching function for call to 'pow' complex<_Tp> z = log(x + sqrt(pow(x, _Tp(2)) - _Tp(1))); ... include/c++/v1/complex:1109:1: note: candidate template ignored: substitution failure [with _Tp = ct::va lue, _Up = ct::value]: no type named 'type' in 'std::1::promote<ct::value, ct::value, void>' pow(const complex<_Tp>& __x, const _Up& y)
The problem here seems to be that std::__promote, which is defined in type_traits, only works for types for which __numeric_type::type exists, and that is only for builtin numeric types. As a result, this template does not match:
template<class _Tp, class _Up> inline _LIBCPP_INLINE_VISIBILITY typename enable_if < is_arithmetic<_Up>::value, complex<typename __promote<_Tp, _Up>::type>