diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 13e834bfb3e..0ae347ee4ff 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,18 @@ 2019-10-24 Jonathan Wakely + * include/bits/allocator.h (allocator): Restore the explicit + specialization for C++20, but make its API consistent with the primary + template. + (allocator::~allocator()): Restore the destructor for C++20, but make + it constexpr. + * testsuite/20_util/allocator/rebind_c++20.cc: Check allocator. + * testsuite/20_util/allocator/requirements/typedefs_c++20.cc: Likewise. + * testsuite/20_util/allocator/void.cc: Check that constructors and + destructors are trivial. Check for converting constructor in C++20. + * testsuite/ext/malloc_allocator/variadic_construct.cc: Simplify + dejagnu target selector. + * testsuite/ext/new_allocator/variadic_construct.cc: Likewise. + * include/experimental/executor (__use_future_ct, use_future_t): Define partial specializations for std::allocator. (__use_future_ch): Overload constructor for completion tokens using diff --git a/libstdc++-v3/include/bits/allocator.h b/libstdc++-v3/include/bits/allocator.h index 1a3eb88eded..2559c57b12e 100644 --- a/libstdc++-v3/include/bits/allocator.h +++ b/libstdc++-v3/include/bits/allocator.h @@ -63,23 +63,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @{ */ -#if __cplusplus <= 201703L /// allocator specialization. template<> class allocator { public: + typedef void value_type; typedef size_t size_type; typedef ptrdiff_t difference_type; +#if __cplusplus <= 201703L typedef void* pointer; typedef const void* const_pointer; - typedef void value_type; template struct rebind { typedef allocator<_Tp1> other; }; +#else + allocator() = default; -#if __cplusplus >= 201103L + template + constexpr + allocator(const allocator<_Up>&) { } +#endif // ! C++20 + +#if __cplusplus >= 201103L && __cplusplus <= 201703L // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2103. std::allocator propagate_on_container_move_assignment typedef true_type propagate_on_container_move_assignment; @@ -98,9 +105,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION destroy(_Up* __p) noexcept(noexcept(__p->~_Up())) { __p->~_Up(); } -#endif // C++11 +#endif // C++11 to C++17 }; -#endif // ! C++20 /** * @brief The @a standard allocator, as per [20.4]. @@ -154,9 +160,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX20_CONSTEXPR allocator(const allocator<_Tp1>&) _GLIBCXX_NOTHROW { } -#if __cplusplus <= 201703L + _GLIBCXX20_CONSTEXPR ~allocator() _GLIBCXX_NOTHROW { } -#endif #if __cplusplus > 201703L [[nodiscard,__gnu__::__always_inline__]] diff --git a/libstdc++-v3/testsuite/20_util/allocator/rebind_c++20.cc b/libstdc++-v3/testsuite/20_util/allocator/rebind_c++20.cc index 968e1de931b..dd7cd67f943 100644 --- a/libstdc++-v3/testsuite/20_util/allocator/rebind_c++20.cc +++ b/libstdc++-v3/testsuite/20_util/allocator/rebind_c++20.cc @@ -23,6 +23,9 @@ template struct Alloc : std::allocator { }; using T = std::allocator_traits>; - // Prior to C++20 this finds std::allocator::rebind and so fails: static_assert( std::is_same_v, Alloc> ); + +using V = std::allocator_traits>; +// Prior to C++20 this finds std::allocator::rebind and so fails: +static_assert( std::is_same_v, Alloc> ); diff --git a/libstdc++-v3/testsuite/20_util/allocator/requirements/typedefs_c++20.cc b/libstdc++-v3/testsuite/20_util/allocator/requirements/typedefs_c++20.cc index e986cc9a809..ef193fb1bf1 100644 --- a/libstdc++-v3/testsuite/20_util/allocator/requirements/typedefs_c++20.cc +++ b/libstdc++-v3/testsuite/20_util/allocator/requirements/typedefs_c++20.cc @@ -54,3 +54,14 @@ static_assert( !has_rebind ); static_assert( !has_construct ); static_assert( !has_destroy ); static_assert( !has_max_size ); + +using V = std::allocator; + +static_assert( !has_pointer ); +static_assert( !has_const_pointer ); +static_assert( !has_reference ); +static_assert( !has_const_reference ); +static_assert( !has_rebind ); +static_assert( !has_construct ); +static_assert( !has_destroy ); +static_assert( !has_max_size ); diff --git a/libstdc++-v3/testsuite/20_util/allocator/void.cc b/libstdc++-v3/testsuite/20_util/allocator/void.cc index d7aa6bd80ed..9d94fac3cc0 100644 --- a/libstdc++-v3/testsuite/20_util/allocator/void.cc +++ b/libstdc++-v3/testsuite/20_util/allocator/void.cc @@ -33,6 +33,28 @@ test01() std::allocator_traits::destroy(a, &i); } +// These properties are formally unspecified, but have always been true for +// the libstdc++ definition of allocator. +static_assert( + std::is_trivially_default_constructible>::value, + "explicit specialization has trivial default constructor"); +static_assert( + std::is_trivially_copy_constructible>::value, + "explicit specialization has trivial copy constructor"); +static_assert( + std::is_trivially_move_constructible>::value, + "explicit specialization has trivial move constructor"); +static_assert( + std::is_trivially_destructible>::value, + "explicit specialization has trivial destructor"); + +#if __cplusplus > 201703L +// C++20 removes the allocator explicit specialization, so it can now be +// constructed using the converting constructor from other specializations. +static_assert( std::is_constructible_v, + std::allocator> ); +#endif + int main() { diff --git a/libstdc++-v3/testsuite/ext/malloc_allocator/variadic_construct.cc b/libstdc++-v3/testsuite/ext/malloc_allocator/variadic_construct.cc index b786fae9f0a..f122768d8ac 100644 --- a/libstdc++-v3/testsuite/ext/malloc_allocator/variadic_construct.cc +++ b/libstdc++-v3/testsuite/ext/malloc_allocator/variadic_construct.cc @@ -1,4 +1,4 @@ -// { dg-do run { target { { c++11_only || c++14_only } || c++17_only } } } +// { dg-do run { target { c++11 && { ! c++2a } } } } // 2007-10-26 Paolo Carlini diff --git a/libstdc++-v3/testsuite/ext/new_allocator/variadic_construct.cc b/libstdc++-v3/testsuite/ext/new_allocator/variadic_construct.cc index 5b23e5b4a2c..cfe93a7b6d9 100644 --- a/libstdc++-v3/testsuite/ext/new_allocator/variadic_construct.cc +++ b/libstdc++-v3/testsuite/ext/new_allocator/variadic_construct.cc @@ -1,4 +1,4 @@ -// { dg-do run { target { { c++11_only || c++14_only } || c++17_only } } } +// { dg-do run { target { c++11 && { ! c++2a } } } } // 2007-10-26 Paolo Carlini