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 <jwak...@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 --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);