diff mbox series

libstdc++: Implement LWG 3149 for std::default_constructible

Message ID 20191115195810.GA3596@redhat.com
State New
Headers show
Series libstdc++: Implement LWG 3149 for std::default_constructible | expand

Commit Message

Jonathan Wakely Nov. 15, 2019, 7:58 p.m. UTC
The change approved in Belfast did not actually rename the concept from
std::default_constructible to std::default_initializable, even though
that was intended. That is expected to be done soon as a separate issue,
so I'm implementing that now too.

	* include/bits/iterator_concepts.h (weakly_incrementable): Adjust.
	* include/std/concepts (default_constructible): Rename to
	default_initializable and require default-list-initialization and
	default-initialization to be valid (LWG 3149).
	(semiregular): Adjust to new name.
	* testsuite/std/concepts/concepts.lang/concept.defaultconstructible/
	1.cc: Rename directory to concept.defaultinitializable and adjust to
	new name.
	* testsuite/std/concepts/concepts.lang/concept.defaultinitializable/
	lwg3149.cc: New test.
	* testsuite/util/testsuite_iterators.h (test_range): Adjust.

Tested powerpc64le-linux, committed to trunk.
commit 7c6d180793479fa8ccc05e0764e90a7b16c48986
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Fri Nov 15 16:31:08 2019 +0000

    libstdc++: Implement LWG 3149 for std::default_constructible
    
    The change approved in Belfast did not actually rename the concept from
    std::default_constructible to std::default_initializable, even though
    that was intended. That is expected to be done soon as a separate issue,
    so I'm implementing that now too.
    
            * include/bits/iterator_concepts.h (weakly_incrementable): Adjust.
            * include/std/concepts (default_constructible): Rename to
            default_initializable and require default-list-initialization and
            default-initialization to be valid (LWG 3149).
            (semiregular): Adjust to new name.
            * testsuite/std/concepts/concepts.lang/concept.defaultconstructible/
            1.cc: Rename directory to concept.defaultinitializable and adjust to
            new name.
            * testsuite/std/concepts/concepts.lang/concept.defaultinitializable/
            lwg3149.cc: New test.
            * testsuite/util/testsuite_iterators.h (test_range): Adjust.
diff mbox series

Patch

diff --git a/libstdc++-v3/include/bits/iterator_concepts.h b/libstdc++-v3/include/bits/iterator_concepts.h
index 90a8bc8071f..3843ba5d57f 100644
--- a/libstdc++-v3/include/bits/iterator_concepts.h
+++ b/libstdc++-v3/include/bits/iterator_concepts.h
@@ -506,7 +506,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   /// Requirements on types that can be incremented with ++.
   template<typename _Iter>
-    concept weakly_incrementable = default_constructible<_Iter>
+    concept weakly_incrementable = default_initializable<_Iter>
       && movable<_Iter>
       && requires(_Iter __i)
       {
diff --git a/libstdc++-v3/include/std/concepts b/libstdc++-v3/include/std/concepts
index e6d405a1bee..98b38940c56 100644
--- a/libstdc++-v3/include/std/concepts
+++ b/libstdc++-v3/include/std/concepts
@@ -138,9 +138,14 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     concept constructible_from
       = destructible<_Tp> && is_constructible_v<_Tp, _Args...>;
 
-  /// [concept.defaultconstructible], concept default_constructible
+  /// [concept.defaultinitializable], concept default_initializable
   template<typename _Tp>
-    concept default_constructible = constructible_from<_Tp>;
+    concept default_initializable = constructible_from<_Tp>
+      && requires
+      {
+	_Tp{};
+	(void) ::new _Tp;
+      };
 
   /// [concept.moveconstructible], concept move_constructible
   template<typename _Tp>
@@ -249,7 +254,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       && assignable_from<_Tp&, const _Tp&>;
 
   template<typename _Tp>
-    concept semiregular = copyable<_Tp> && default_constructible<_Tp>;
+    concept semiregular = copyable<_Tp> && default_initializable<_Tp>;
 
   // [concepts.compare], comparison concepts
 
diff --git a/libstdc++-v3/testsuite/std/concepts/concepts.lang/concept.defaultconstructible/1.cc b/libstdc++-v3/testsuite/std/concepts/concepts.lang/concept.defaultinitializable/1.cc
similarity index 50%
rename from libstdc++-v3/testsuite/std/concepts/concepts.lang/concept.defaultconstructible/1.cc
rename to libstdc++-v3/testsuite/std/concepts/concepts.lang/concept.defaultinitializable/1.cc
+++ b/libstdc++-v3/testsuite/std/concepts/concepts.lang/concept.defaultinitializable/1.cc
@@ -20,28 +20,28 @@ 
 
 #include <concepts>
 
-static_assert( !std::default_constructible<void> );
-static_assert( std::default_constructible<void*> );
-static_assert( std::default_constructible<const void*> );
-static_assert( std::default_constructible<char> );
-static_assert( std::default_constructible<float> );
-static_assert( std::default_constructible<const int> );
-static_assert( std::default_constructible<int*> );
-static_assert( !std::default_constructible<int&> );
-static_assert( !std::default_constructible<int&&> );
-static_assert( !std::default_constructible<const int&> );
-static_assert( !std::default_constructible<int[]> );
-static_assert( std::default_constructible<int[2]> );
-static_assert( !std::default_constructible<int()> );
-static_assert( std::default_constructible<int(*)()> );
-static_assert( !std::default_constructible<int(&)()> );
+static_assert( !std::default_initializable<void> );
+static_assert( std::default_initializable<void*> );
+static_assert( std::default_initializable<const void*> );
+static_assert( std::default_initializable<char> );
+static_assert( std::default_initializable<float> );
+static_assert( !std::default_initializable<const int> );
+static_assert( std::default_initializable<int*> );
+static_assert( !std::default_initializable<int&> );
+static_assert( !std::default_initializable<int&&> );
+static_assert( !std::default_initializable<const int&> );
+static_assert( !std::default_initializable<int[]> );
+static_assert( std::default_initializable<int[2]> );
+static_assert( !std::default_initializable<int()> );
+static_assert( std::default_initializable<int(*)()> );
+static_assert( !std::default_initializable<int(&)()> );
 
 enum E { };
-static_assert( std::default_constructible<E> );
+static_assert( std::default_initializable<E> );
 enum class CE { };
-static_assert( std::default_constructible<CE> );
+static_assert( std::default_initializable<CE> );
 struct A { };
-static_assert( std::default_constructible<A> );
+static_assert( std::default_initializable<A> );
 union B { };
 static_assert( std::constructible_from<B> );
 
@@ -50,7 +50,7 @@  struct C
   C(void* = nullptr) { }
   ~C() noexcept(false) { }
 };
-static_assert( !std::default_constructible<C> );
+static_assert( !std::default_initializable<C> );
 
 class D
 {
@@ -60,4 +60,4 @@  public:
 private:
   ~D() { }
 };
-static_assert( !std::default_constructible<D> );
+static_assert( !std::default_initializable<D> );
diff --git a/libstdc++-v3/testsuite/std/concepts/concepts.lang/concept.defaultinitializable/lwg3149.cc b/libstdc++-v3/testsuite/std/concepts/concepts.lang/concept.defaultinitializable/lwg3149.cc
new file mode 100644
index 00000000000..024601ba864
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/concepts/concepts.lang/concept.defaultinitializable/lwg3149.cc
@@ -0,0 +1,43 @@ 
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <concepts>
+
+// Default-initialization of const T is only valid for class types that are
+// const-default-constructible.
+static_assert( !std::default_initializable<const int> );
+static_assert( !std::default_initializable<const int[1]> );
+struct A { int i; };
+static_assert( !std::default_initializable<const A> );
+static_assert( !std::default_initializable<const A[1]> );
+struct B { int i; long l; };
+static_assert( !std::default_initializable<const B> );
+static_assert( !std::default_initializable<const B[1]> );
+struct C : A { };
+static_assert( !std::default_initializable<const C> );
+static_assert( !std::default_initializable<const C[1]> );
+struct D { A a; };
+static_assert( !std::default_initializable<const D> );
+static_assert( !std::default_initializable<const D[1]> );
+
+struct S0 { explicit S0() = default; };
+struct S1 { S0 x; }; // Note: aggregate
+// S1{} would be ill-formed, due to copy-list-initialization of S1::x from {}
+static_assert( !std::default_initializable<S1> );
diff --git a/libstdc++-v3/testsuite/util/testsuite_iterators.h b/libstdc++-v3/testsuite/util/testsuite_iterators.h
index 4c5e9a3cc1d..13993a4209b 100644
--- a/libstdc++-v3/testsuite/util/testsuite_iterators.h
+++ b/libstdc++-v3/testsuite/util/testsuite_iterators.h
@@ -682,7 +682,7 @@  namespace __gnu_test
       auto
       get_iterator(T* p)
       {
-	if constexpr (std::default_constructible<Iter<T>>)
+	if constexpr (std::default_initializable<Iter<T>>)
 	  return Iter<T>(p, &bounds);
 	else
 	  return iterator(p, &bounds);