[libcxx-commits] [libcxx] r373092 - [libc++] Take 2: Implement LWG 3158

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Fri Sep 27 08:06:53 PDT 2019


Author: ldionne
Date: Fri Sep 27 08:06:52 2019
New Revision: 373092

URL: http://llvm.org/viewvc/llvm-project?rev=373092&view=rev
Log:
[libc++] Take 2: Implement LWG 3158

Summary:
LWG 3158 marks the allocator_arg_t constructor of std::tuple as
conditionnally explicit based on whether the default constructors
of the tuple's members are explicitly default constructible.

This was previously committed as r372778 and reverted in r372832 due to
the commit breaking LLVM's build in C++14 mode. This issue has now been
addressed.

Reviewers: mclow.lists

Subscribers: christof, jkorous, dexonsmith, libcxx-commits

Tags: #libc

Differential Revision: https://reviews.llvm.org/D65232

Added:
    libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc.fail.cpp
Modified:
    libcxx/trunk/include/tuple
    libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc.pass.cpp
    libcxx/trunk/www/cxx2a_status.html
    libcxx/trunk/www/upcoming_meeting.html

Modified: libcxx/trunk/include/tuple
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/tuple?rev=373092&r1=373091&r2=373092&view=diff
==============================================================================
--- libcxx/trunk/include/tuple (original)
+++ libcxx/trunk/include/tuple Fri Sep 27 08:06:52 2019
@@ -500,20 +500,22 @@ class _LIBCPP_TEMPLATE_VIS tuple
     struct _CheckArgsConstructor<true, _Dummy>
     {
         template <class ..._Args>
-        static constexpr bool __enable_implicit_default() {
+        struct __enable_implicit_default
             // In C++03, there's no way to implement the resolution of LWG2510.
 #ifdef _LIBCPP_CXX03_LANG
-            return true;
+            : true_type
 #else
-            return __all<__is_implicitly_default_constructible<_Args>::value...>::value;
+            : __all<__is_implicitly_default_constructible<_Args>::value...>
 #endif
-        }
+        { };
 
         template <class ..._Args>
-        static constexpr bool __enable_explicit_default() {
-            return __all<is_default_constructible<_Args>::value...>::value
-                && !__enable_implicit_default<_Args...>();
-        }
+        struct __enable_explicit_default
+            : integral_constant<bool,
+                __all<is_default_constructible<_Args>::value...>::value &&
+                !__enable_implicit_default<_Args...>::value
+            >
+        { };
 
         template <class ..._Args>
         static constexpr bool __enable_explicit() {
@@ -653,14 +655,14 @@ class _LIBCPP_TEMPLATE_VIS tuple
 public:
 
     template <bool _Dummy = true, _EnableIf<
-        _CheckArgsConstructor<_Dummy>::template __enable_implicit_default<_Tp...>()
+        _CheckArgsConstructor<_Dummy>::template __enable_implicit_default<_Tp...>::value
     , void*> = nullptr>
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
     tuple()
         _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
 
     template <bool _Dummy = true, _EnableIf<
-        _CheckArgsConstructor<_Dummy>::template __enable_explicit_default<_Tp...>()
+        _CheckArgsConstructor<_Dummy>::template __enable_explicit_default<_Tp...>::value
     , void*> = nullptr>
     explicit _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
     tuple()
@@ -669,17 +671,31 @@ public:
     tuple(tuple const&) = default;
     tuple(tuple&&) = default;
 
-    template <class _AllocArgT, class _Alloc, bool _Dummy = true, class = _EnableIf<
+    template <class _AllocArgT, class _Alloc, bool _Dummy = true, _EnableIf<
         _And<
             _IsSame<allocator_arg_t, _AllocArgT>,
-           __dependent_type<is_default_constructible<_Tp>, _Dummy>...
+            typename _CheckArgsConstructor<_Dummy>::template __enable_implicit_default<_Tp...>
        >::value
-      >
+      , void*> = nullptr
     >
     _LIBCPP_INLINE_VISIBILITY
     tuple(_AllocArgT, _Alloc const& __a)
       : __base_(allocator_arg_t(), __a,
                     __tuple_indices<>(), __tuple_types<>(),
+                    typename __make_tuple_indices<sizeof...(_Tp), 0>::type(),
+                    __tuple_types<_Tp...>()) {}
+
+    template <class _AllocArgT, class _Alloc, bool _Dummy = true, _EnableIf<
+        _And<
+            _IsSame<allocator_arg_t, _AllocArgT>,
+            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<sizeof...(_Tp), 0>::type(),
                     __tuple_types<_Tp...>()) {}
 

Added: libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc.fail.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc.fail.cpp?rev=373092&view=auto
==============================================================================
--- libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc.fail.cpp (added)
+++ libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc.fail.cpp Fri Sep 27 08:06:52 2019
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03
+
+// <tuple>
+
+// template <class... Types> class tuple;
+
+// template <class Alloc>
+//   explicit(see-below) tuple(allocator_arg_t, const Alloc& a);
+
+// Make sure we get the explicit-ness of the constructor right.
+// This is LWG 3158.
+
+#include <tuple>
+#include <memory>
+
+
+struct ExplicitDefault { explicit ExplicitDefault() { } };
+
+std::tuple<ExplicitDefault> explicit_default_test() {
+    return {std::allocator_arg, std::allocator<int>()}; // expected-error {{chosen constructor is explicit in copy-initialization}}
+}
+
+int main(int, char**) {
+    return 0;
+}

Modified: libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc.pass.cpp?rev=373092&r1=373091&r2=373092&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/alloc.pass.cpp Fri Sep 27 08:06:52 2019
@@ -13,7 +13,7 @@
 // template <class... Types> class tuple;
 
 // template <class Alloc>
-//   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

Modified: libcxx/trunk/www/cxx2a_status.html
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/www/cxx2a_status.html?rev=373092&r1=373091&r2=373092&view=diff
==============================================================================
--- libcxx/trunk/www/cxx2a_status.html (original)
+++ libcxx/trunk/www/cxx2a_status.html Fri Sep 27 08:06:52 2019
@@ -358,7 +358,7 @@
 	<tr><td><a href="https://wg21.link/LWG3182">3182</a></td><td>Specification of <tt>Same</tt> could be clearer</td><td>Kona</td><td></td></tr>
 
 	<tr><td></td><td></td><td></td><td></td></tr>
-	<tr><td><a href="https://wg21.link/LWG2899">2899</a></td><td><tt>is_(nothrow_)move_constructible</tt> and <tt>tuple</tt>, <tt>optional</tt> and <tt>unique_ptr</tt></td><td>Cologne</td><td></td></tr>
+	<tr><td><a href="https://wg21.link/LWG2899">2899</a></td><td><tt>is_(nothrow_)move_constructible</tt> and <tt>tuple</tt>, <tt>optional</tt> and <tt>unique_ptr</tt></td><td>Cologne</td><td>Complete</td></tr>
 	<tr><td><a href="https://wg21.link/LWG3055">3055</a></td><td><tt>path::operator+=(<i>single-character</i>)</tt> misspecified</td><td>Cologne</td><td></td></tr>
 	<tr><td><a href="https://wg21.link/LWG3158">3158</a></td><td><tt>tuple(allocator_arg_t, const Alloc&)</tt> should be conditionally explicit</td><td>Cologne</td><td></td></tr>
 	<tr><td><a href="https://wg21.link/LWG3169">3169</a></td><td><tt>ranges</tt> permutation generators discard useful information</td><td>Cologne</td><td></td></tr>

Modified: libcxx/trunk/www/upcoming_meeting.html
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/www/upcoming_meeting.html?rev=373092&r1=373091&r2=373092&view=diff
==============================================================================
--- libcxx/trunk/www/upcoming_meeting.html (original)
+++ libcxx/trunk/www/upcoming_meeting.html Fri Sep 27 08:06:52 2019
@@ -61,7 +61,7 @@
 <tr><th>Issue #</th><th>Has P/R</th><th>Issue Name</th><th>Meeting</th><th>Status</th></tr>
 <tr><td><a href="https://wg21.link/LWG2899">2899</a></td><td>Yes</td><td><tt>is_(nothrow_)move_constructible</tt> and <tt>tuple</tt>, <tt>optional</tt> and <tt>unique_ptr</tt></td><td>Cologne</td><td></td></tr>
 <tr><td><a href="https://wg21.link/LWG3055">3055</a></td><td>Yes</td><td><tt>path::operator+=(<i>single-character</i>)</tt> misspecified</td><td>Cologne</td><td></td></tr>
-<tr><td><a href="https://wg21.link/LWG3158">3158</a></td><td>Yes</td><td><tt>tuple(allocator_arg_t, const Alloc&)</tt> should be conditionally explicit</td><td>Cologne</td><td></td></tr>
+<tr><td><a href="https://wg21.link/LWG3158">3158</a></td><td>Yes</td><td><tt>tuple(allocator_arg_t, const Alloc&)</tt> should be conditionally explicit</td><td>Cologne</td><td>Complete</td></tr>
 <tr><td><a href="https://wg21.link/LWG3169">3169</a></td><td>Yes</td><td><tt>ranges</tt> permutation generators discard useful information</td><td>Cologne</td><td></td></tr>
 <tr><td><a href="https://wg21.link/LWG3183">3183</a></td><td>Yes</td><td>Normative permission to specialize Ranges variable templates</td><td>Cologne</td><td></td></tr>
 <tr><td><a href="https://wg21.link/LWG3184">3184</a></td><td>Yes</td><td>Inconsistencies in <tt>bind_front</tt> wording</td><td>Cologne</td><td></td></tr>
@@ -95,7 +95,6 @@
 <ul>
 <li>2899 - Louis</li>
 <li>3055 - Eric?</li>
-<li>3158 - Louis</li>
 <li>3169 - We don't do ranges yet</li>
 <li>3183 - We don't do ranges yet</li>
 <li>3184 - We don't do bind_front yet</li>




More information about the libcxx-commits mailing list