According to the formula for 'common_type', as an abominable function type does not have a valid return type for 'declval', the trait should not have a nested 'type' name. The following program shows this is not the case (I have not tried to work out what the nested name aliases, probably the type itself): template <typename TestType, typename = void> inline constexpr bool DetectType = false; template <typename TestType > inline constexpr bool DetectType<TestType, std::void_t<typename TestType::type>> = true; // Quick proof detector works correctly struct NoType {}; struct HasType { using type = HasType; }; static_assert( DetectType<HasType> ); static_assert(!DetectType<NoType> ); auto main() -> int { static_assert(!DetectType< std::common_type<int( ) & > >); static_assert(!DetectType< std::common_type<int(...) & > >); static_assert(!DetectType< std::common_type<int( ) & noexcept> >); static_assert(!DetectType< std::common_type<int(...) & noexcept> >); return 0; } I have also tested with gcc9 in development, but MacPorts stopped updating around October 2018, so my test environment is quite out of date - so only claiming the bug against the latest release version I have tested.
We implement the C++14 rules still, where common_type<T>::type is just decay<T>::type.
That changed with P0548R1 (which is not a DR).
Author: redi Date: Wed Feb 6 17:25:26 2019 New Revision: 268586 URL: https://gcc.gnu.org/viewcvs?rev=268586&root=gcc&view=rev Log: PR libstdc++/89102 fix common_type<> and common_type<T> specializations This is a partial implementation of the revised std::common_type rules from P0435R1. PR libstdc++/89102 (partial) * include/std/type_traits (common_type<>): Define. (common_type<T>): Derive from common_type<T, T>. * testsuite/20_util/common_type/requirements/explicit_instantiation.cc: Test zero-length template argument list. * testsuite/20_util/common_type/requirements/sfinae_friendly_1.cc: Test additional single argument cases. * testsuite/20_util/common_type/requirements/sfinae_friendly_2.cc: Adjust expected error. Modified: trunk/libstdc++-v3/ChangeLog trunk/libstdc++-v3/include/std/type_traits trunk/libstdc++-v3/testsuite/20_util/common_type/requirements/explicit_instantiation.cc trunk/libstdc++-v3/testsuite/20_util/common_type/requirements/sfinae_friendly_1.cc trunk/libstdc++-v3/testsuite/20_util/common_type/requirements/sfinae_friendly_2.cc
Minimal fix committed to trunk, with a complete fix posted to https://gcc.gnu.org/ml/gcc-patches/2019-02/msg00346.html for stage 1.
GCC 8.3 has been released.
Author: redi Date: Tue May 7 15:46:44 2019 New Revision: 270968 URL: https://gcc.gnu.org/viewcvs?rev=270968&root=gcc&view=rev Log: PR libstdc++/89102 fix common_type<> and common_type<T> specializations This is a partial implementation of the revised std::common_type rules from P0435R1. Backport from mainline 2019-02-06 Jonathan Wakely <jwakely@redhat.com> PR libstdc++/89102 (partial) * include/std/type_traits (common_type<>): Define. (common_type<T>): Derive from common_type<T, T>. * testsuite/20_util/common_type/requirements/explicit_instantiation.cc: Test zero-length template argument list. * testsuite/20_util/common_type/requirements/sfinae_friendly_1.cc: Test additional single argument cases. * testsuite/20_util/common_type/requirements/sfinae_friendly_2.cc: Adjust expected error. Modified: branches/gcc-8-branch/libstdc++-v3/ChangeLog branches/gcc-8-branch/libstdc++-v3/include/std/type_traits branches/gcc-8-branch/libstdc++-v3/testsuite/20_util/common_type/requirements/explicit_instantiation.cc branches/gcc-8-branch/libstdc++-v3/testsuite/20_util/common_type/requirements/sfinae_friendly_1.cc branches/gcc-8-branch/libstdc++-v3/testsuite/20_util/common_type/requirements/sfinae_friendly_2.cc
Author: redi Date: Tue May 7 22:46:39 2019 New Revision: 270987 URL: https://gcc.gnu.org/viewcvs?rev=270987&root=gcc&view=rev Log: PR libstdc++/89102 implement new common_type rules (P0435R1, P0548R1) This change ensures that std::common_type<> is a complete type (LWG 2408), and that std::common_type<T>, std::common_type<cv T1, cv T2>, and std::common_type<T1, T2, R...> will use program-defined specializations for std::common_type<T1, T2> (LWG 2465). The implementation of common_type<T1, T2, R...> is changed to use void_t, and the specializations for duration and time_point are modified to also use void_t instead of depending on implementation details of common_type. PR libstdc++/89102 * doc/xml/manual/intro.xml: Document DR 2408 and 2465 changes. * include/std/chrono (__duration_common_type_wrapper): Replace with ... (__duration_common_type): New helper. (common_type<chrono::duration<R1, P2>, chrono::duration<R2, P2>>): Use __duration_common_type. (__timepoint_common_type_wrapper): Replace with ... (__timepoint_common_type): New helper. (common_type<chrono::time_point<C, D2>, chrono::time_point<C, D2>>): Use __time_point_common_type. * include/std/type_traits (common_type<>): Define, as per LWG 2408. (__common_type_impl): If either argument is transformed by decay, use the common_type of the decayed types. (__common_type_impl<_Tp, _Up, _Tp, _Up>): If the types are already decayed, use __do_common_type_impl to get the common_type. (common_type<_Tp>): Use common_type<_Tp, _Tp>. (__do_member_type_wrapper, __member_type_wrapper) (__expanded_common_type_wrapper): Remove. (__common_type_pack, __common_type_fold): New helpers. (common_type<_Tp, _Up, _Vp...>): Use new helpers instead of __member_type_wrapper and __expanded_common_type_wrapper. * testsuite/20_util/common_type/requirements/explicit_instantiation.cc: Test zero-length template argument list. * testsuite/20_util/common_type/requirements/sfinae_friendly_1.cc: Test single argument cases and argument types that should decay. * testsuite/20_util/common_type/requirements/sfinae_friendly_2.cc: Adjust expected error. * testsuite/20_util/duration/literals/range_neg.cc: Use zero for dg-error lineno. * testsuite/20_util/duration/requirements/typedefs_neg1.cc: Likewise. * testsuite/20_util/duration/requirements/typedefs_neg2.cc: Likewise. * testsuite/20_util/duration/requirements/typedefs_neg3.cc: Likewise. Modified: trunk/libstdc++-v3/ChangeLog trunk/libstdc++-v3/doc/xml/manual/intro.xml trunk/libstdc++-v3/include/std/chrono trunk/libstdc++-v3/include/std/type_traits trunk/libstdc++-v3/testsuite/20_util/common_type/requirements/sfinae_friendly_1.cc trunk/libstdc++-v3/testsuite/20_util/duration/literals/range_neg.cc trunk/libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg1.cc trunk/libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg2.cc trunk/libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg3.cc
The abominable function types handling is fixed for gcc 8.4 and the full C++2a common_type spec is implemented on trunk now.
The master branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>: https://gcc.gnu.org/g:82030d51017323c5706d58d8c8626324ece007e4 commit r11-2913-g82030d51017323c5706d58d8c8626324ece007e4 Author: Jonathan Wakely <jwakely@redhat.com> Date: Thu Aug 27 22:36:03 2020 +0100 libstdc++: Make std::chrono::duration use reduced ratio for period This implements the changes from P0548 "common_type and duration". That was a change for C++17, but as it corrects some issues introduced by DRs I'm also treating it as a DR and changing it for all modes from C++11 up. The main change is that duration<R,P>::period no longer denotes P, but rather P::type, the reduced ratio. The unary operator+ and operator- members of duration should now return a duration using that reduced ratio. The requirement that common_type<T>::type is the same type as common_type<T, T>::type (rather than simply T) was already implemented for PR 89102. The standard says that duration::operator+() and duration::operator-() should return common_type_t<duration>, but that seems unnecessarily expensive to compute. This change just uses duration<rep, period> which is the same type, so we don't need to instantiate common_type. As an optimization, this also adds partial specializations of common_type for two durations of the same type, a single duration, two time_points of the same type, and a single time_point. These specializations avoid instantiating other specializations of common_type and one or both of __duration_common_type or __timepoint_common_type for the cases where the answer is trivial to obtain. libstdc++-v3/ChangeLog: * include/std/chrono (__duration_common_type): Ensure the reduced ratio is used. Remove unused partial specialization using __failure_type. (common_type): Pass reduced ratios to __duration_common_type. Add partial specializations for simple cases involving a single duration or time_point type. (duration::period): Use reduced ratio. (duration::operator+(), duration::operator-()): Return duration type using the reduced ratio. * testsuite/20_util/duration/requirements/typedefs_neg2.cc: Adjust expected errors. * testsuite/20_util/duration/requirements/reduced_period.cc: New test.
The releases/gcc-10 branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>: https://gcc.gnu.org/g:7dea2f84f26d454331d34b8536c261b6e96205d7 commit r10-9608-g7dea2f84f26d454331d34b8536c261b6e96205d7 Author: Jonathan Wakely <jwakely@redhat.com> Date: Thu Aug 27 22:36:03 2020 +0100 libstdc++: Make std::chrono::duration use reduced ratio for period This implements the changes from P0548 "common_type and duration". That was a change for C++17, but as it corrects some issues introduced by DRs I'm also treating it as a DR and changing it for all modes from C++11 up. The main change is that duration<R,P>::period no longer denotes P, but rather P::type, the reduced ratio. The unary operator+ and operator- members of duration should now return a duration using that reduced ratio. The requirement that common_type<T>::type is the same type as common_type<T, T>::type (rather than simply T) was already implemented for PR 89102. The standard says that duration::operator+() and duration::operator-() should return common_type_t<duration>, but that seems unnecessarily expensive to compute. This uses duration<common_type_t<rep>, period> which is the same type, so we avoid a common_type specialization. As an optimization, this also adds partial specializations of common_type for two durations of the same type, a single duration, two time_points of the same type, and a single time_point. These specializations avoid instantiating other specializations of common_type and one or both of __duration_common_type or __timepoint_common_type for the cases where the answer is trivial to obtain. libstdc++-v3/ChangeLog: * include/std/chrono (__duration_common_type): Ensure the reduced ratio is used. Remove unused partial specialization using __failure_type. (common_type): Pass reduced ratios to __duration_common_type. Add partial specializations for simple cases involving a single duration or time_point type. (duration::period): Use reduced ratio. (duration::operator+(), duration::operator-()): Return duration type using the reduced ratio. * testsuite/20_util/duration/requirements/typedefs_neg2.cc: Adjust expected errors. * testsuite/20_util/duration/requirements/reduced_period.cc: New test. (cherry picked from commit 82030d51017323c5706d58d8c8626324ece007e4)