diff --git a/libcxx/include/tuple b/libcxx/include/tuple --- a/libcxx/include/tuple +++ b/libcxx/include/tuple @@ -489,15 +489,17 @@ struct _CheckArgsConstructor { template - static constexpr bool __enable_implicit_default() { - return __all<__is_implicitly_default_constructible<_Args>::value...>::value; - } + struct __enable_implicit_default + : __all<__is_implicitly_default_constructible<_Args>::value...> + { }; template - static constexpr bool __enable_explicit_default() { - return __all::value...>::value - && !__enable_implicit_default<_Args...>(); - } + struct __enable_explicit_default + : integral_constant::value...>::value && + !__enable_implicit_default<_Args...>::value + > + { }; template static constexpr bool __enable_explicit() { @@ -637,14 +639,14 @@ public: template ::template __enable_implicit_default<_Tp...>() + _CheckArgsConstructor<_Dummy>::template __enable_implicit_default<_Tp...>::value , void*> = nullptr> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR tuple() _NOEXCEPT_(__all::value...>::value) {} template ::template __enable_explicit_default<_Tp...>() + _CheckArgsConstructor<_Dummy>::template __enable_explicit_default<_Tp...>::value , void*> = nullptr> explicit _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR tuple() @@ -653,12 +655,12 @@ tuple(tuple const&) = default; tuple(tuple&&) = default; - template , - __dependent_type, _Dummy>... + typename _CheckArgsConstructor<_Dummy>::template __enable_implicit_default<_Tp...> >::value - > + , void*> = nullptr > _LIBCPP_INLINE_VISIBILITY tuple(_AllocArgT, _Alloc const& __a) @@ -667,6 +669,20 @@ typename __make_tuple_indices::type(), __tuple_types<_Tp...>()) {} + template , + typename _CheckArgsConstructor<_Dummy>::template __enable_explicit_default<_Tp...> + >::value + , void*> = nullptr + > + explicit _LIBCPP_INLINE_VISIBILITY + tuple(_AllocArgT, _Alloc const& __a) + : __base_(allocator_arg_t(), __a, + __tuple_indices<>(), __tuple_types<>(), + typename __make_tuple_indices::type(), + __tuple_types<_Tp...>()) {} + template + +// template class tuple; + +// template +// explicit(see-below) tuple(allocator_arg_t, const Alloc& a); + +// UNSUPPORTED: c++98, c++03 + +// Make sure we get the explicit-ness of the constructor right. +// This is LWG 3158. + +#include +#include + + +struct ExplicitDefault { explicit ExplicitDefault() { } }; + +std::tuple explicit_default_test() { + return {std::allocator_arg, std::allocator()}; // expected-error {{chosen constructor is explicit in copy-initialization}} +} + +int main(int, char**) { + return 0; +} diff --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc.pass.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc.pass.cpp --- a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc.pass.cpp +++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc.pass.cpp @@ -13,7 +13,7 @@ // template class tuple; // template -// tuple(allocator_arg_t, const Alloc& a); +// explicit(see-below) tuple(allocator_arg_t, const Alloc& a); // NOTE: this constructor does not currently support tags derived from // allocator_arg_t because libc++ has to deduce the parameter as a template diff --git a/libcxx/www/upcoming_meeting.html b/libcxx/www/upcoming_meeting.html --- a/libcxx/www/upcoming_meeting.html +++ b/libcxx/www/upcoming_meeting.html @@ -61,7 +61,7 @@ Issue #Has P/RIssue NameMeetingStatus 2899Yesis_(nothrow_)move_constructible and tuple, optional and unique_ptrCologne 3055Yespath::operator+=(single-character) misspecifiedCologne -3158Yestuple(allocator_arg_t, const Alloc&) should be conditionally explicitCologne +3158Yestuple(allocator_arg_t, const Alloc&) should be conditionally explicitCologneComplete 3169Yesranges permutation generators discard useful informationCologne 3183YesNormative permission to specialize Ranges variable templatesCologne 3184YesInconsistencies in bind_front wordingCologne @@ -95,7 +95,6 @@
  • 2899 - Louis
  • 3055 - Eric?
  • -
  • 3158 - Louis
  • 3169 - We don't do ranges yet
  • 3183 - We don't do ranges yet
  • 3184 - We don't do bind_front yet