https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90700
--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> --- Author: redi Date: Thu Jun 6 12:13:36 2019 New Revision: 271998 URL: https://gcc.gnu.org/viewcvs?rev=271998&root=gcc&view=rev Log: Refactor SFINAE constraints on std::tuple constructors Replace the _TC class template with the better-named _TupleConstraints one, which provides a different set of member functions. The new members do not distinguish construction from lvalues and rvalues, but expects the caller to do that by providing different template arguments. Within the std::tuple primary template and std::tuple<T1, T2> partial specialization the _TupleConstraints members are used via new alias templates like _ImplicitCtor and _ExplicitCtor which makes the constructor constraints less verbose and repetitive. For example, where we previously had: template<typename... _UElements, typename enable_if< _TMC<_UElements...>::template _MoveConstructibleTuple<_UElements...>() && _TMC<_UElements...>::template _ImplicitlyMoveConvertibleTuple<_UElements...>() && (sizeof...(_Elements) >= 1), bool>::type=true> constexpr tuple(_UElements&&... __elements) We now have: template<typename... _UElements, bool _Valid = __valid_args<_UElements...>(), _ImplicitCtor<_Valid, _UElements...> = true> constexpr tuple(_UElements&&... __elements) There are two semantic changes as a result of the refactoring: - The allocator-extended default constructor is now constrained. - The rewritten constraints fix PR 90700. * include/std/tuple (_TC): Replace with _TupleConstraints. (_TupleConstraints): New helper for SFINAE constraints, with more expressive member functions to reduce duplication when used. (tuple::_TC2, tuple::_TMC, tuple::_TNTC): Remove. (tuple::_TCC): Replace dummy type parameter with bool non-type parameter that can be used to check the pack size. (tuple::_ImplicitDefaultCtor, tuple::_ExplicitDefaultCtor) (tuple::_ImplicitCtor, tuple::_ExplicitCtor): New alias templates for checking constraints in constructors. (tuple::__valid_args, tuple::_UseOtherCtor, tuple::__use_other_ctor): New SFINAE helpers. (tuple::tuple): Use new helpers to reduce repitition in constraints. (tuple::tuple(allocator_arg_t, const Alloc&)): Constrain. (tuple<T1, T2>::_TCC, tuple<T1, T2>::_ImplicitDefaultCtor) (tuple<T1, T2>::_ExplicitDefaultCtor, tuple<T1, T2>::_ImplicitCtor) (tuple<T1, T2>::_ExplicitCtor): New alias templates for checking constraints in constructors. (tuple::__is_alloc_arg()): New SFINAE helpers. (tuple<T1, T2>::tuple): Use new helpers to reduce repitition in constraints. (tuple<T1, T2>::tuple(allocator_arg_t, const Alloc&)): Constrain. * testsuite/20_util/tuple/cons/90700.cc: New test. * testsuite/20_util/tuple/cons/allocators.cc: Add default constructor to meet new constraint on allocator-extended default constructor. Added: trunk/libstdc++-v3/testsuite/20_util/tuple/cons/90700.cc Modified: trunk/libstdc++-v3/ChangeLog trunk/libstdc++-v3/include/std/tuple trunk/libstdc++-v3/testsuite/20_util/tuple/cons/allocators.cc