[libc++] Un-deprecate and un-remove some members of std::allocator

This implements the part of P0619R4 related to the default allocator.
This is incredibly important, since otherwise there is an ABI break
between C++17 and C++20 w.r.t. the default allocator's size_type on
platforms where std::size_t is not the same as std::make_unsigned<std::ptrdiff_t>.
This commit is contained in:
Louis Dionne 2020-08-28 12:31:16 -04:00
parent 4ca60915bc
commit 316d336dca
9 changed files with 95 additions and 56 deletions

View File

@ -115,8 +115,8 @@ template <class T>
class allocator
{
public:
typedef size_t size_type; // deprecated in C++17, removed in C++20
typedef ptrdiff_t difference_type; // deprecated in C++17, removed in C++20
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T* pointer; // deprecated in C++17, removed in C++20
typedef const T* const_pointer; // deprecated in C++17, removed in C++20
typedef typename add_lvalue_reference<T>::type
@ -1748,9 +1748,9 @@ template <class _Tp>
class _LIBCPP_TEMPLATE_VIS allocator
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)
_LIBCPP_DEPRECATED_IN_CXX17 typedef size_t size_type;
_LIBCPP_DEPRECATED_IN_CXX17 typedef ptrdiff_t difference_type;
_LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp* pointer;
_LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp* const_pointer;
_LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp& reference;
@ -1816,9 +1816,9 @@ template <class _Tp>
class _LIBCPP_TEMPLATE_VIS allocator<const _Tp>
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)
_LIBCPP_DEPRECATED_IN_CXX17 typedef size_t size_type;
_LIBCPP_DEPRECATED_IN_CXX17 typedef ptrdiff_t difference_type;
_LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp* pointer;
_LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp* const_pointer;
_LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp& reference;

View File

@ -8,7 +8,8 @@
// <memory>
// check nested types:
// Check that the following types are provided regardless of the Standard when
// we request them from libc++.
// template <class T>
// class allocator
@ -45,5 +46,5 @@ int main(int, char**)
static_assert((std::is_same<std::allocator<char>::rebind<int>::other,
std::allocator<int> >::value), "");
return 0;
return 0;
}

View File

@ -8,6 +8,9 @@
// <memory>
// Check that the following member types of allocator<void> are provided
// regardless of the Standard when we request them from libc++.
// template <>
// class allocator<void>
// {

View File

@ -8,16 +8,14 @@
// <memory>
// check nested types:
// Check that the following nested types are deprecated in C++17:
// template <class T>
// class allocator
// {
// public:
// typedef size_t size_type;
// typedef ptrdiff_t difference_type;
// typedef T* pointer;
// typedef const T* const_pointer;
// typedef T* pointer;
// typedef const T* const_pointer;
// typedef typename add_lvalue_reference<T>::type reference;
// typedef typename add_lvalue_reference<const T>::type const_reference;
//
@ -25,28 +23,27 @@
// ...
// };
// Deprecated in C++17
// UNSUPPORTED: c++03, c++11, c++14
// REQUIRES: c++17
// Clang 6 does not handle the deprecated attribute on template members properly,
// so the rebind<int> check below fails.
// UNSUPPORTED: clang-6
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS
#include <memory>
#include "test_macros.h"
int main(int, char**)
{
typedef std::allocator<char>::size_type AST; // expected-warning {{'size_type' is deprecated}}
typedef std::allocator<char>::difference_type ADT; // expected-warning {{'difference_type' is deprecated}}
typedef std::allocator<char>::pointer AP; // expected-warning {{'pointer' is deprecated}}
typedef std::allocator<char>::const_pointer ACP; // expected-warning {{'const_pointer' is deprecated}}
typedef std::allocator<char>::reference AR; // expected-warning {{'reference' is deprecated}}
typedef std::allocator<char>::const_reference ACR; // expected-warning {{'const_reference' is deprecated}}
typedef std::allocator<char>::rebind<int>::other ARO; // expected-warning {{'rebind<int>' is deprecated}}
return 0;
typedef std::allocator<char const>::pointer AP2; // expected-warning {{'pointer' is deprecated}}
typedef std::allocator<char const>::const_pointer ACP2; // expected-warning {{'const_pointer' is deprecated}}
typedef std::allocator<char const>::reference AR2; // expected-warning {{'reference' is deprecated}}
typedef std::allocator<char const>::const_reference ACR2; // expected-warning {{'const_reference' is deprecated}}
typedef std::allocator<char const>::rebind<int>::other ARO2; // expected-warning {{'rebind<int>' is deprecated}}
return 0;
}

View File

@ -8,12 +8,14 @@
// <memory>
// check nested types:
// Check that the nested types of std::allocator are provided:
// template <class T>
// class allocator
// {
// public:
// typedef size_t size_type;
// typedef ptrdiff_t difference_type;
// typedef T value_type;
//
// typedef true_type propagate_on_container_move_assignment;
@ -27,21 +29,25 @@
#include "test_macros.h"
template <typename T, typename U>
void check()
{
static_assert((std::is_same<typename std::allocator<T>::size_type, std::size_t>::value), "");
static_assert((std::is_same<typename std::allocator<T>::difference_type, std::ptrdiff_t>::value), "");
static_assert((std::is_same<typename std::allocator<T>::value_type, T>::value), "");
static_assert((std::is_same<typename std::allocator<T>::propagate_on_container_move_assignment, std::true_type>::value), "");
static_assert((std::is_same<typename std::allocator<T>::is_always_equal, std::true_type>::value), "");
std::allocator<T> a;
std::allocator<T> a2 = a;
a2 = a;
std::allocator<U> a3 = a2;
(void)a3;
}
int main(int, char**)
{
static_assert((std::is_same<std::allocator<char>::value_type, char>::value), "");
static_assert((std::is_same<std::allocator<char>::propagate_on_container_move_assignment, std::true_type>::value), "");
LIBCPP_STATIC_ASSERT((std::is_same<std::allocator<const char>::propagate_on_container_move_assignment, std::true_type>::value), "");
static_assert((std::is_same<std::allocator<char>::is_always_equal, std::true_type>::value), "");
LIBCPP_STATIC_ASSERT((std::is_same<std::allocator<const char>::is_always_equal, std::true_type>::value), "");
std::allocator<char> a;
std::allocator<char> a2 = a;
a2 = a;
std::allocator<int> a3 = a2;
((void)a3);
return 0;
check<char, int>();
check<char const, int const>();
return 0;
}

View File

@ -0,0 +1,46 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
// <memory>
// Check that the following nested types are removed in C++20:
// template <class T>
// class allocator
// {
// public:
// typedef T* pointer;
// typedef const T* const_pointer;
// typedef typename add_lvalue_reference<T>::type reference;
// typedef typename add_lvalue_reference<const T>::type const_reference;
//
// template <class U> struct rebind {typedef allocator<U> other;};
// ...
// };
// UNSUPPORTED: c++03, c++11, c++14, c++17
#include <memory>
#include "test_macros.h"
template <typename T>
void check()
{
typedef typename std::allocator<T>::pointer AP; // expected-error 2 {{no type named 'pointer'}}
typedef typename std::allocator<T>::const_pointer ACP; // expected-error 2 {{no type named 'const_pointer'}}
typedef typename std::allocator<T>::reference AR; // expected-error 2 {{no type named 'reference'}}
typedef typename std::allocator<T>::const_reference ACR; // expected-error 2 {{no type named 'const_reference'}}
typedef typename std::allocator<T>::template rebind<int>::other ARO; // expected-error 2 {{no member named 'rebind'}}
}
int main(int, char**)
{
check<char>();
check<char const>();
return 0;
}

View File

@ -7,23 +7,10 @@
//===----------------------------------------------------------------------===//
// <memory>
//
// template <>
// class allocator<void>
// {
// public:
// typedef void* pointer;
// typedef const void* const_pointer;
// typedef void value_type;
//
// template <class _Up> struct rebind {typedef allocator<_Up> other;};
// };
//
// Deprecated in C++17
// UNSUPPORTED: c++03, c++11, c++14
// Check that allocator<void> is deprecated in C++17.
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS
// REQUIRES: c++17
#include <memory>
#include "test_macros.h"
@ -33,6 +20,5 @@ int main(int, char**)
typedef std::allocator<void>::pointer AP; // expected-warning {{'allocator<void>' is deprecated}}
typedef std::allocator<void>::const_pointer ACP; // expected-warning {{'allocator<void>' is deprecated}}
typedef std::allocator<void>::rebind<int>::other ARO; // expected-warning {{'allocator<void>' is deprecated}}
return 0;
return 0;
}

View File

@ -105,7 +105,7 @@
<tr><td><a href="https://wg21.link/p0088r3">p0088r3</a></td><td>LWG</td><td>Variant: a type-safe union for C++17</td><td>Oulu</td><td>Complete</td><td>4.0</td></tr>
<tr><td><a href="https://wg21.link/p0137r1">p0137r1</a></td><td>CWG</td><td>Core Issue 1776: Replacement of class objects containing reference members</td><td>Oulu</td><td>Complete</td><td>6.0</td></tr>
<tr><td><a href="https://wg21.link/p0163r0">p0163r0</a></td><td>LWG</td><td>shared_ptr::weak_type</td><td>Oulu</td><td>Complete</td><td>3.9</td></tr>
<tr><td><a href="https://wg21.link/p0174r2">p0174r2</a></td><td>LWG</td><td>Deprecating Vestigial Library Parts in C++17</td><td>Oulu</td><td></td><td></td></tr>
<tr><td><a href="https://wg21.link/p0174r2">p0174r2</a></td><td>LWG</td><td>Deprecating Vestigial Library Parts in C++17</td><td>Oulu</td><td>Partial</td><td></td></tr>
<tr><td><a href="https://wg21.link/p0175r1">p0175r1</a></td><td>LWG</td><td>Synopses for the C library</td><td>Oulu</td><td></td><td></td></tr>
<tr><td><a href="https://wg21.link/p0180r2">p0180r2</a></td><td>LWG</td><td>Reserve a New Library Namespace for Future Standardization</td><td>Oulu</td><td><i>Nothing to do</i></td><td>n/a</td></tr>
<tr><td><a href="https://wg21.link/p0181r1">p0181r1</a></td><td>LWG</td><td>Ordered by Default</td><td>Oulu</td><td><i>Removed in Kona</i></td><td>n/a</td></tr>

View File

@ -89,7 +89,7 @@
<tr><td><a href="https://wg21.link/P0528R3">P0528R3</a></td><td>CWG</td><td>The Curious Case of Padding Bits, Featuring Atomic Compare-and-Exchange</td><td>Rapperswil</td><td></td><td></td></tr>
<tr><td><a href="https://wg21.link/P0542R5">P0542R5</a></td><td>CWG</td><td>Support for contract based programming in C++</td><td>Rapperswil</td><td></td><td></td></tr>
<tr><td><a href="https://wg21.link/P0556R3">P0556R3</a></td><td>LWG</td><td>Integral power-of-2 operations</td><td>Rapperswil</td><td>Complete</td><td>9.0</td></tr>
<tr><td><a href="https://wg21.link/P0619R4">P0619R4</a></td><td>LWG</td><td>Reviewing Deprecated Facilities of C++17 for C++20</td><td>Rapperswil</td><td></td><td></td></tr>
<tr><td><a href="https://wg21.link/P0619R4">P0619R4</a></td><td>LWG</td><td>Reviewing Deprecated Facilities of C++17 for C++20</td><td>Rapperswil</td><td>Partial<br>(only std::allocator part is implemented)</td><td></td></tr>
<tr><td><a href="https://wg21.link/P0646R1">P0646R1</a></td><td>LWG</td><td>Improving the Return Value of Erase-Like Algorithms</td><td>Rapperswil</td><td>Complete</td><td>10.0</td></tr>
<tr><td><a href="https://wg21.link/P0722R3">P0722R3</a></td><td>CWG</td><td>Efficient sized delete for variable sized classes</td><td>Rapperswil</td><td>Complete</td><td>9.0</td></tr>
<tr><td><a href="https://wg21.link/P0758R1">P0758R1</a></td><td>LWG</td><td>Implicit conversion traits and utility functions</td><td>Rapperswil</td><td>Complete</td><td></td></tr>